好的,所以我发现了新的 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/