swift - Swift 3 中的 dispatch_once 去哪儿了?

标签 swift grand-central-dispatch swift3 libdispatch

好的,所以我发现了新的 Swifty Dispatch API在 Xcode 8 中。我使用 DispatchQueue.main.async 很开心,我一直在浏览 Xcode 中的 Dispatch 模块以查找所有新 API。

但我还使用 dispatch_once 来确保诸如单例创建和一次性设置之类的事情不会被执行多次(即使在多线程环境中)......和 ​​新的 Dispatch 模块中找不到 dispatch_once

static var token: dispatch_once_t = 0
func whatDoYouHear() {
    print("All of this has happened before, and all of it will happen again.")
    dispatch_once(&token) {
        print("Except this part.")
    }
}

最佳答案

从 Swift 1.x 开始,Swift 一直在使用 dispatch_once behind the scenes执行全局变量和静态属性的线程安全惰性初始化。

所以上面的 static var 已经在使用 dispatch_once,这使得它有点奇怪(并且可能有问题再次使用它作为另一个 dispatch_once 的标记。事实上,如果不使用这种递归,确实没有安全的方法来使用 dispatch_once,因此他们放弃了它。相反,只需使用基于它构建的语言功能:

// global constant: SomeClass initializer gets called lazily, only on first use
let foo = SomeClass()

// global var, same thing happens here
// even though the "initializer" is an immediately invoked closure
var bar: SomeClass = {
    let b = SomeClass()
    b.someProperty = "whatever"
    b.doSomeStuff()
    return b
}()

// ditto for static properties in classes/structures/enums
class MyClass {
    static let singleton = MyClass()
    init() {
        print("foo")
    }
}

因此,如果您一直使用 dispatch_once 进行一次性初始化并产生某个值,那就太好了——您可以将该值设置为全局变量或您正在初始化的静态属性。

但是,如果您使用 dispatch_once 进行不一定有结果的工作怎么办?您仍然可以使用全局变量或静态属性来执行此操作:只需将该变量的类型设置为 Void:

let justAOneTimeThing: () = {
    print("Not coming back here.")
}()

如果访问全局变量或静态属性来执行一次性工作对您来说并不合适——比如说,您希望您的客户在使用您的库之前调用“初始化我”函数——只需将该访问包装在一个函数中:

func doTheOneTimeThing() {
    justAOneTimeThing
}

参见 migration guide更多。

关于swift - Swift 3 中的 dispatch_once 去哪儿了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37801407/

相关文章:

swift GCD : Why signal handler doesn't work in function

iOS的dispatch_get_global_queue嵌套在dispatch_get_main_queue中

ios - 如何让 dispatch_async 运行

ios - Swift 3 - 禁用和启用分段控制

swift - 扩展与 LocationPermission 类

swift - 如何利用 Root.plist 中的默认值进行 Swift 应用程序设置

ios - 快速发送和接收推送通知

swift - 从范围中获取索引值

swift - 我如何在 Swift 3、Swift 4 及更高版本中使用 dispatch_sync、dispatch_async、dispatch_after 等?

swift - 在 xCode 10-beta 1 上使用随 pod 安装的 Firebase 时出错