【发布时间】:2015-12-10 13:51:44
【问题描述】:
到目前为止我看到的答案(1、2、3)建议使用 GCD 的dispatch_once,因此:
var token: dispatch_once_t = 0
func test() {
dispatch_once(&token) {
print("This is printed only on the first call to test()")
}
print("This is printed for each call to test()")
}
test()
输出:
This is printed only on the first call to test()
This is printed for each call to test()
但是等一下。 token 是一个变量,所以我可以很容易地做到这一点:
var token: dispatch_once_t = 0
func test() {
dispatch_once(&token) {
print("This is printed only on the first call to test()")
}
print("This is printed for each call to test()")
}
test()
token = 0
test()
输出:
This is printed only on the first call to test()
This is printed for each call to test()
This is printed only on the first call to test()
This is printed for each call to test()
所以如果我可以更改token 的值,dispatch_once 将毫无用处!将token 转换为常量并不简单,因为它需要UnsafeMutablePointer<dispatch_once_t> 类型。
那么我们应该放弃 Swift 中的dispatch_once 吗?有没有更安全的方法来执行一次代码?
【问题讨论】:
-
Objective-C 也有同样的问题。想法是将
token放在与dispatch_once块相同的范围内(并给它一个更好的名称,例如onceToken,并将其放在dispatch_once块本身的正上方,以便非常清楚)。跨度> -
那么
dispatch_once并不比使用普通的布尔变量更安全。 -
Eric,关于使用普通 bool 与
dispatch_once的问题对于 Stack Overflow 来说可能是一个更好的讨论。我很想看到那个答案(如果这里还没有被问及回答)。 -
最新的答案(如您的参考文献 #1 和 #3 中)确实不推荐 GCD,而是一个静态类属性(它以线程安全的方式延迟初始化) .
标签: swift grand-central-dispatch