IOS -- Singleton design mode (excerpt, non-original) in Swift development, iosswift
Recently, I have developed a small application and encountered some common Singleton modes in Objective-c, but there are some differences in swift, I tried to find out that I couldn't play the cards by using common sense (normal oc to swift), so I searched some posts. It may be a problem with xcode or sdk (I believe they will not display untested code, right ?...), The code in some posts made obvious errors and compilation failed. So I will share this article with you.
The original author implemented a Singleton, but the red code causesNon-thread security:
1 class var sharedInstance:TPScopeManager { 2 get { 3 struct Static { 4 static var instance : TPScopeManager? = nil 5 } 6 7 if !Static.instance { 8 Static.instance = TPScopeManager() 9 }10 11 return Static.instance!12 }13 }
So with the following solutions (I personally feel wonderful ):
Global constant
First: directly declare global variables
let _SingletonSharedInstance = Singleton()class Singleton { ...}
Advantage: the code is the most concise.
Disadvantage: Code openness is messy
The second method makes up for the shortcomings above.
private let _SingletonSharedInstance = Singleton()class Singleton { class var sharedInstance : Singleton { return _SingletonSharedInstance }}
Note: Because type constants (static constants of the class) are not supported, global constants are used here.
This method supports lasy initialization because Swift delays global constants (and variables) initialization and the let keyword is thread-safe. (Implication: The global variables also delay initialization, but are not thread-safe? I'm not sure. Please enlighten me)
Nested struct (Estimate and translate it into internal struct)
class Singleton { class var sharedInstance : Singleton { struct Static { static let instance : Singleton = Singleton() } return Static.instance }}
The class does not support type constants (static constants of the class), but struct does. This can achieve similar results.
We recommend that you use the internal struct method in the original article, unless the type variable is supported in the new version.
Dispatch_once (this cannot be translated)
The traditional OC method is also supported in Swift. Compared with the previous method, this method obviously has no advantages, but write it out.
class Singleton { class var sharedInstance : Singleton { struct Static { static var onceToken : dispatch_once_t = 0 static var instance : Singleton? = nil } dispatch_once(&Static.onceToken) { Static.instance = Singleton() } return Static.instance! }}
(In the same principle, we still use struct to support type variables to translate the dispatch_once method of OC)
As mentioned above, Apple has clearly stated that delayed Initialization is thread-safe. Therefore, there is no need to add dispatch_once or similar protection measures.
The essence of delayed loading of global variables (static members inside struct and enum are also the same) is dispatch_once. Therefore, if you want to use dispatch_once, you should declare a private global variable directly to ensure thread security, it will not make the code too open
I prefer the global variable method (optimized of course), without having to nest a layer of struct, Which is concise. What do you like?
Good English can directly view the original post http://stackoverflow.com/questions/24024549/dispatch-once-singleton-model-in-swift