I'm trying to work out an appropriate singleton model for usage in Swift. So far, I've been able to get a non-thread safe model working as:
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
}
if !Static.instance {
Static.instance = TPScopeManager()
}
return Static.instance!
}
}
Wrapping the singleton instance in the Static struct should allow a single instance that doesn't collide with singleton instances without complex naming schemings, and it should make things fairly private. Obviously though, this model isn't thread-safe. So I tried to add dispatch_once
to the whole thing:
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!
}
}
But I get a compiler error on the dispatch_once
line:
Cannot convert the expression's type 'Void' to type '()'
I've tried several different variants of the syntax, but they all seem to have the same results:
dispatch_once(Static.token, { Static.instance = TPScopeManager() })
What is the proper usage of dispatch_once
using Swift? I initially thought the problem was with the block due to the ()
in the error message, but the more I look at it, the more I think it may be a matter of getting the dispatch_once_t
correctly defined.
@lazy
should be thread safe. – SulthanStatic.instance = TPScopeManager()
forces the instance type. If you use something likeStatic.instance = self()
with a required initializer, the appropriate type class will be generated. Even so, and this is the important thing to note, only once for all instances in the hierarchy! First type to initialize is the type set for all instances. I don't think objective-c behaved the same. – sean woodward