【问题标题】:Using dispatch_once or static vars in a lazy var在惰性变量中使用 dispatch_once 或静态变量
【发布时间】:2023-03-31 08:45:01
【问题描述】:

来自Swift guide

如果一个带有lazy修饰符的属性被多个线程同时访问,而该属性还没有被初始化,则不能保证该属性只会被初始化一次。

所以,据我了解,使用

class SomeClass {
    lazy var someVar: SomeOtherClass = {
       return SomeOtherClass()
    }()
}

不是确保使用 SomeClass 实例的每个人都使用与 SomeClass().someVar 相同的 SomeOtherClass 实例的线程安全方式。

如果是这样的话,正在使用

class SomeClass {
    lazy var someVarr: SomeOtherClass = {
        var some: SomeOtherClass? = nil
        var token: dispatch_once_t = 0
        dispatch_once(&token) {
            some = SomeOtherClass()
        }
        return some!
    }()
}

或使用:

class SomeClass {
    lazy var someVarrr: SomeOtherClass = {
        struct Static {
            static let some = SomeOtherClass()
        }
        return Static.some
    }()
}

实例化 SomeOtherClass 的正确、线程安全的方式?

为了提供一些上下文:在 Objective-C 中,我使用了:

-(NSURLSession *)ephemeralURLSession {
    if (!_ephemeralURLSession) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
            _ephemeralURLSession = [NSURLSession sessionWithConfiguration:configuration];
        });
    }
    return _ephemeralURLSession;
}

现在我想知道在 Swift 中实例化 NSURLSession 的正确方法是什么,例如:

lazy var ephemeralURLSession: NSURLSession = {
    var session: NSURLSession? = nil
    var token: dispatch_once_t = 0
    dispatch_once(&token) {
        let configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.ephemeralSessionConfiguration()
        session = NSURLSession(configuration: configuration)
    }
    return session!
}()

【问题讨论】:

    标签: ios multithreading swift


    【解决方案1】:

    你可以这样定义:

    static let ephemeralURLSession: NSURLSession = {
        let configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration()
        return NSURLSession(configuration: configuration)
    }()
    

    这既是惰性的又是线程安全的。

    【讨论】:

    • 如果我想为类的每个实例创建一个新的ephemeralURLSession
    • 这段代码不允许你这样做,因为它声明了一个type property,它在对象的所有实例之间共享。如果这是您需要的,请查看 page 75 of this book 可能会有所帮助。
    • 那是相当多的代码。我希望有更简洁的东西。但感谢您的链接和回答。
    • 不客气,我希望你也能找到更漂亮的东西,但看起来你最好使用一个常量 NSURLSession,如果它不是必须使用的,你最好在你的类的 init 函数中初始化一个懒惰的变量。
    猜你喜欢
    • 2011-08-14
    • 2017-05-13
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    相关资源
    最近更新 更多