Recently, I took over some projects, singleton writing method is multifarious, at first glance, I feel confused, sum up
- Writing a
Static members automatically meet the dispatch_once rule
Final class Single1 {var name: String = "Single1" static let shared = Single1() private init() {}}Copy the code
Of course, you have to have something else to do when you initialize a singleton, and you can distort it a little bit
final class Single1 { var name: Static let shared = {let instance = Single1() return instance}() private init() {}}Copy the code
- Note: The init method must be private so that singletons are truly unique, preventing external objects from creating additional instances of the singleton class by accessing the init method.
I copied the following paragraph
Now, you might be wondering: why can’t you see dispatch_once? According to the Apple Swift blog, all of the above methods automatically satisfy the Dispatch_once rule. Here’s a post that proves that the Dispatch_once rule has always been in effect. The Lazy initialization method for global variables (as well as static members of structs and enumerators) is called once when they are accessed. Similar to calling ‘dispatch_once’ to ensure atomicity of its initialization. There’s a cool ‘single call’ approach: just declare a global variable and a private initialization method.” — From Apple’s Swift Blo (” The lazy Initializer for a global variable (also for static members of structs and enums) is run the first time that global is accessed, and is launched as dispatch_once to make sure that the initialization is atomic. This enables a cool way to use dispatch_once in your code: Just declare a global variable with an Initializer and mark it private. “) That’s all the official Apple documentation gives us, But this is enough to prove that global variables and static members of structs/enumerators support the “dispatch_once” feature. We now believe it is 100% safe to use global variables to “lazily wrap” the initialization methods of a singleton into a dispatch_once code block.
- Refer to the Swift singleton Apple documentation
- Write 2
Principle: Global variables are used to automatically meet the dispatch_once rule
Private let single2 = single2 () final class single2 {var name: String = "single2" static var shared: Single2 { single2 } fileprivate init() {} }Copy the code
- Writing 3
Static dispatch_once (dispatch_once); static dispatch_once (dispatch_once)
Final class Single3{var name: String = "Single3" static var shared: Single3{struct SingleStruct {static let instance: Single3 = Single3() } return SingleStruct.instance } private init() {} }Copy the code
- Write 4
Principle: same as method 3, calculate attribute change function only, and calculate attribute essence is function
final class Single4 { var name: String = "static func shared() -> Single4 {struct SingleStruct {static var single = Single4()} return SingleStruct.single } }Copy the code
- Write five
Principle: in fact, there is no difference with the front, OC is enchanted, not to use the whole dispatch_once_t, pure took off his pants fart, the most not recommended
Public extension DispatchQueue {private static var onceToken: DispatchQueue {private static var onceToken: DispatchQueue; String = "" // Ensure that things nested by this function are always executed once like dispatch_once_t String, block:@escaping () -> Void) { objc_sync_enter(self) defer { objc_sync_exit(self) } if onceToken.contains(token){ return }} // use dispatch_once_t to break wind. Single5 { struct SingleStruct { static var instance: Single5? = nil } DispatchQueue.once(token: "single5") { SingleStruct.instance = Single5() } return SingleStruct.instance! }}Copy the code
- Common mistakes
Here again, the calculation of a property is the same as a function, which is the same as calling the initialization function, so be careful
static var share: Class func 'default' () -> ImagePickerTool {ImagePickerTool()} {ImagePickerTool()}Copy the code