Singleton mode may be one of the most commonly used patterns in iOS development, but due to the language characteristics of OC itself, it is relatively troublesome to write a correct singleton mode, here I would like to talk about the design of the singleton mode in iOS. Please refer to this article for more information on the singleton mode.
As the name implies, there can be only one instance of a class, in the Java, C + + languages, you can avoid duplicate creation of objects by privatizing them, but Objective-c is not able to do so, and we need to do this through other mechanisms. In general, we may write a singleton pattern like this:
#import <Foundation/Foundation.h> @interface singleton:nsobject+ (instancetype) shareinstance @end #import " Singleton.h "@implementation singletonstatic singleton* _instance = nil;+ (instancetype) shareinstance{ static dispatch_once_t Oncetoken; Dispatch_once (&oncetoken, ^{ _instance = [[Self alloc] init]; }); return _instance;} @end
Specific use:
#import <Foundation/Foundation.h> #import "Singleton.h" int main (int argc, const char * argv[]) { @ Autoreleasepool { singleton* obj1 = [Singleton shareinstance]; NSLog (@ "obj1 =%@.", obj1); singleton* obj2 = [Singleton shareinstance]; NSLog (@ "obj2 =%@.", obj2); singleton* obj3 = [[Singleton alloc] init]; NSLog (@ "obj3 =%@.", obj3); } return 0;}
The output is:
2014-12-15 16:06:28.344 objcsingleton[8847:303] obj1 = <singleton:0x1001086e0>.2014-12-15 16:06:28.346 objcsingleton[8847:303] Obj2 = <singleton:0x1001086e0>.2014-12-15 16:06:28.346 objcsingleton[8847:303] obj3 = <singleton:0x100103940>.
As you can see, the objects we get when we call the Shareinstance method are the same, but when we construct the objects through Alloc and init, we get different objects.
So the problem is that we get different objects in different ways, obviously not. We have to ensure the uniqueness of the object, so we need to block the way the user constructs the object through Alloc and init and copy.
We know that the steps to create the object are divided into the application memory (ALLOC), initialization (init) steps, we want to ensure the uniqueness of the object, so at this stage of the first step we have to intercept it. When we call the Alloc method, OC will call Allocwithzone this method to request memory, we override this method, and then call the Shareinstance method in this method to return the singleton object, so that we can achieve our purpose. Copying an object is the same principle, overwrite the Copywithzone method, and then call the Shareinstance method in this method to return the singleton object. Look at the code:
#import "Singleton.h" @implementation singletonstatic singleton* _instance = nil;+ (instancetype) shareinstance{ Static dispatch_once_t Oncetoken; Dispatch_once (&oncetoken, ^{ _instance = [[Super Allocwithzone:null] init]; }); return _instance;} + (ID) allocwithzone: (struct _nszone *) zone{ return [Singleton shareinstance];} -(ID) Copywithzone: (struct _nszone *) zone{ return [Singleton shareinstance];} @end
and see how it works:
Main: #import <Foundation/Foundation.h> #import "Singleton.h" int main (int argc, const char * argv[]) { @autorel Easepool { singleton* obj1 = [Singleton shareinstance]; NSLog (@ "obj1 =%@.", obj1); singleton* obj2 = [Singleton shareinstance]; NSLog (@ "obj2 =%@.", obj2); singleton* obj3 = [[Singleton alloc] init]; NSLog (@ "obj3 =%@.", obj3); singleton* OBJ4 = [[Singleton alloc] init]; NSLog (@ "OBJ4 =%@.", [obj4 Copy]); } return 0;}
Output Result:
2014-12-15 16:11:24.734 objcsingleton[8979:303] obj1 = <singleton:0x100108720>.2014-12-15 16:11:24.735 objcsingleton[8979:303] Obj2 = <singleton:0x100108720>.2014-12-15 16:11:24.736 objcsingleton[8979:303] obj3 = <singleton:0x100108720>.2014-12-15 16:11:24.736 objcsingleton[8979:303] obj4 = <singleton:0x100108720>.
you can see that the objects you get are the same.
The idea is this, if there are more rigorous wording, please leave a message to inform. Thank you ~
The correct wording of objective-c single-case pattern