'dispatch_once_t'在Swift中不可用:使用延迟初始化的全局变量而不是

时间:2016-07-22 01:27:48

标签: swift swift3

迁移到Swift 3时遇到dispatch_once_t问题。

根据Apple's migration guide

  

免费功能dispatch_once在Swift中不再可用。在   Swift,你可以使用延迟初始化的全局变量或静态属性   获得与dispatch_once相同的线程安全和被叫一次保证   提供。例如:

     

let myGlobal = { … global contains initialization in a call to a closure … }()

     

_ = myGlobal // using myGlobal will invoke the initialization code only the first time it is used.

所以我想迁移这段代码。所以它是在迁移之前:

class var sharedInstance: CarsConfigurator
{
    struct Static {
        static var instance: CarsConfigurator?
        static var token: dispatch_once_t = 0
    }

    dispatch_once(&Static.token) {
        Static.instance = CarsConfigurator()
    }

    return Static.instance!
}

迁移后,按照Apple的指导原则(手动迁移),代码如下所示:

class var sharedInstance: CarsConfigurator
{
    struct Static {
        static var instance: CarsConfigurator?
        static var token = {0}()
    }

    _ = Static.token

    return Static.instance!
}

但是当我运行此操作时,访问return Static.instance!时会出现以下错误:

  

致命错误:在解包可选值时意外发现nil

我从这个错误中看到instance成员是nil,但为什么会这样?我的迁移有问题吗?

1 个答案:

答案 0 :(得分:18)

该代码过于冗长,即使它在Swift 2中有效。在Swift 3中,Apple强制您通过闭包使用延迟初始化:

class CarsConfigurator {
    static let sharedInstance: CarsConfigurator = { CarsConfigurator() }()
}