dispatch_once_t 是类型别名 (Int)。头文件:
/*!
* @typedef dispatch_once_t
*
* @abstract
* A predicate for use with dispatch_once(). It must be initialized to zero.
* Note: static and global variables default to zero.
*/
typealias dispatch_once_t = Int
这是来自dispatch_once 文档的引用:
谓词必须指向存储在全局或静态中的变量
范围。使用自动或动态谓词的结果
存储(包括 Objective-C 实例变量)未定义。
token 变量必须存储在全局/静态范围内,并且必须初始化为零,这导致了这段代码:
import Foundation
var token: dispatch_once_t = 0
dispatch_once(&token) { () -> Void in
print("Called once")
}
如果您省略 = 0(token 初始化),它将不起作用,因为编译器会产生错误在初始化之前获取变量“token”的地址,尽管静态和全局变量默认为零。在 Xcode 7B2 中测试。
更多示例基于评论。如果您在 class 方法中,则有多种可能性。
您不能在方法内声明静态属性,否则编译器会产生静态属性只能在类型错误时声明。这不起作用:
class func doItOnce() {
static var token: dispatch_once_t = 0
...
}
必须在类型上声明。这是在 Swift 1.2 (Xcode 6.3 IIRC) 中引入的。
现在允许在类中使用“静态”方法和属性(作为
“类决赛”的别名)。您现在可以声明静态存储
类中的属性,具有全局存储并且是惰性的
在首次访问时初始化(如全局变量)。现在的协议
将类型要求声明为“静态”要求,而不是
将它们声明为“类”要求。 (17198298)
那么,如果我们不喜欢全局变量,我们该怎么办?
类型上的静态变量
class MyClass {
private static var token: dispatch_once_t = 0
class func doItOnce() {
dispatch_once(&token) {
print("Do it once")
}
}
}
结构体中的静态方法
不喜欢你班级的静态属性?想在您的方法中使用它吗?将其包装在这样的结构中:
class func doItOnce() {
struct Tokens { static var token: dispatch_once_t = 0 }
dispatch_once(&Tokens.token) {
print("Do it once")
}
}
实际上,我不知道任何 Apple 建议、最佳实践……如何为 dispatch_once 做这件事。只需使用您最喜欢、对您感觉良好且符合标准全局/静态范围的任何内容。