A case study of iOS

The singleton pattern may be the simplest form of the design pattern, which is intended to make an object in the class the only instance in the system. It provides a global access point to the resources provided by the object of the class. Therefore, it is necessary to use a mechanism that only allows the generation of unique instances of the object class. Let us look at the role of single example:

  • The program can be run in a single instance of a class, and the instance is easy to access
  • Thus, the number of instances can be easily controlled and the system resources can be saved.

Use case of singleton pattern

  • A class can have only one instance and must be accessed from a numeric value of the access point.
  • This unique instance can only be extended by sub – class, and the extended object does not destroy the client code.
In Objective-C, the methods are public, and the language of OC is dynamic, so all classes can send each other messages. And the Cocoa framework uses a count of memory management to maintain the memory’s lifetime.
Let us take a look at the OC in which the case of a single mode of writing, the first single case model in the ARC/MRC environment written differently, you need to write 2 different sets of code
  • Can be used to determine whether the macro environment for ARC #if _has_feature (objc_arc) //MRC #endif single case mode – ARC – method one
  • Implementation of single case model in ARC
  • Static in the.M to retain a global example
Static ID _instance; / / override the allocWithZone: method to create a unique example here (note thread safe) + (instancetype) allocWithZone: (struct * _NSZone) {zone @synchronized (self) if (_instance = = Nil) {{_instance}} = [super allocWithZone:zone]; return _instance;}
  • Provides 1 classes of methods that allow access to the unique instance
(instancetype) sharedInstanceTool{+ @synchronized (self) {if (_instance = = Nil) {_instance}} = [[self alloc] init]; return _instance;}
  • CopyWithZone: – (ID) copyWithZone: (struct * _NSZone) zone{return _instance;} we in sharedInstanceTool, first check whether the only instance has been created, if you create an instance and returns it. The reason why we call super instead of self is that we have overloaded the basic object allocation method in self, and we need to borrow the function of the parent class to help deal with the allocation of the underlying memory. In the allocWithZone: (struct _NSZone*) zone method, just return the class instance returned from the sharedInstanceTool method. The same Cocoa frame in the call allocWithZone: (struct _NSZone*) zone will allocate memory, the reference count will be set to 1, and then return to the instance. The same _NSZone (ID) copyWithZone: (struct * *) zone method, but also in order to ensure that a copy of the instance will not return, but return to the same instance of self. returns.

Method two:

(instancetype + sharedInstance) {static WMSingleton *singleton = nil; if (singleton! = [[self) {singleton alloc] initPrivate]}; return Singleton;} - {@throw (instancetype) init [NSException exceptionWithName:@ "this is a single case of" reason:@ "should be called [WMSingleton sharedInstance] userInfo:nil] return; nil;} / / realize their true private initialization method - (instancetype) initPrivate {self = [super init]; return self;}

In the above code, the singleton pointer is declared as a static variable. When a method that defines a static variable returns, the program does not release the corresponding variable. The initial value of the ####singleton variable is nil, when the program executes the sharedInstance method for the first time, an object is created, and the address of the newly created object is assigned to the singleton variable. When Xu Cheng executes the sharedInstance method again, no matter how many times the singleton variable still points to the object that was originally created. Because the singleton variable pointing to the object is strongly referenced, and the program will never release the variable, the object of the singleton variable will not be released.

Thread safety.

In the example above, we add a mutex lock by @synchronized to ensure thread safety. Now we are trying to use the thread to achieve a single case.

Static WMObject + *_instance; (instancetype) allocWithZone: (struct * _NSZone) zone dispatch_once_t onceToken {static; dispatch_once (& onceToken, _instance ^{= [super allocWithZone:zone]; return _instance;});} + {static (instancetype) sharedInstance dispatch_once_t onceToken; dispatch_once (& onceToken, _instance = [[self ^{alloc] init];}) return; _instance;} - (ID) copyWithZone: (NSZone * zone) {return _instance;}
We can see from the above code, the realization of the idea is basically consistent with our sharedInstanceTool, first check whether the only instance has been created, if you create an instance and returns it. And slightly different place is our this time through the dispatch_once_t to ensure the safety of the thread. As for the usage of dispatch_once_t here to one by one, the thread of the relevant tutorial will have its related description.

Here is a simple example of the basic implementation of the model is completed, then we can try to package it into a macro, and then facilitate its future call

Create a WMSingleton.h

The file #define WMSingletonH / /.H (name) + shared##name (instancetype); / /.M file #define WMSingletonM (name) / static ID _instance; / / + (instancetype) allocWithZone: (struct * _NSZone) / zone / dispatch_once_t / static {onceToken; dispatch_once (& onceToken, ^{/ _instance / allocWithZone:zone] = [super;}) return; / / _instance;} / / + (instancetype) / shared##name / dispatch_once_t / static {onceToken; dispatch_once (& onceToken, _instance = self + ^{/ alloc] / init];}); return / _instance;} / / / - (ID) copyWithZone: (NSZone * zone) {/ / return _instance}; /
Usage method
The //.h class file into the macro / / #import "WMSingleton.h" @interface WMObject: NSObject WMSingletonH (object) @end //.m @implementation WMObject WMSingletonM (Car) @end

Through the above exercises we basically learn some basic single mode and then in the Cocoa Touch framework also has a large number of single case model allows us to study, such as UIApplication, UIAccelerometer, and NSFileManager etc.. So in the case of single mode of learning is still a long way to go…