在惰性var中使用dispatch_once或static vars

时间:2016-03-04 10:18:48

标签: ios multithreading swift

来自Swift guide

  

如果同时由多个线程访问标记为lazy修饰符的属性且该属性尚未初始化,则无法保证该属性仅初始化一次。

所以,据我所知,使用

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

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

如果是这种情况,请使用

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!
}()

1 个答案:

答案 0 :(得分:4)

您可以这样定义:

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

这是懒惰和线程安全的。