我正在尝试找出适合在Swift中使用的单例模型.到目前为止,我已经能够得到一个非线程安全模型:
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
}
if !Static.instance {
Static.instance = TPScopeManager()
}
return Static.instance!
}
}
Run Code Online (Sandbox Code Playgroud)
在Static结构中包装单例实例应允许单个实例在没有复杂命名方案的情况下不与单例实例发生冲突,并且它应该使事情变得相当私密.显然,这个模型不是线程安全的,所以我尝试将dispatch_once添加到整个事情中:
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
static var token: dispatch_once_t = 0
}
dispatch_once(Static.token) { Static.instance = TPScopeManager() }
return Static.instance!
}
}
Run Code Online (Sandbox Code Playgroud)
但我得到一个编译器错误dispatch_once:
无法将表达式的类型'Void'转换为'()'类型
我已经尝试了几种不同的语法变体,但它们似乎都有相同的结果:
dispatch_once(Static.token, { Static.instance = TPScopeManager() })
Run Code Online (Sandbox Code Playgroud)
dispatch_once使用Swift 的正确用法是什么?我最初认为问题出在块中,因为dispatch_once错误消息,但我看的越多,我认为可能是获得() …
好的,所以我在Xcode 8中发现了新的Swifty Dispatch API.我很开心使用DispatchQueue.main.async,我一直在浏览DispatchXcode中的模块以找到所有新的API.
但我也用它dispatch_once来确保像单例创建和一次性设置这样的事情不会被多次执行(即使在多线程环境中)......并且dispatch_once在新的Dispatch模块中找不到它?
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.")
}
}
Run Code Online (Sandbox Code Playgroud) 我dispatch_once_t在迁移到Swift 3 时遇到了麻烦.
根据Apple的迁移指南:
Swift中不再提供免费函数dispatch_once.在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!
}
Run Code Online (Sandbox Code Playgroud)
迁移后,遵循Apple的指导原则(手动迁移),代码如下所示:
class var sharedInstance: CarsConfigurator
{
struct Static …Run Code Online (Sandbox Code Playgroud)