Reference: HTTP://BLOG.CSDN.NET/LOVEFQING/ARTICLE/DETAILS/8516536#T3
http://blog.csdn.net/kindazrael/article/details/7917863
The singleton pattern is used when a class can have only one instance, typically this "singleton " represents a physical device such as a printer, or some kind of virtual resource or system attribute, such as a program's engine or data, that can not have multiple instances at the same time. The simplest example is that when the user opens the QQ space to play music, here is a singleton, if not a single case, click on other pages QQ music will automatically start from the beginning. It is necessary to control it with a single-case pattern.
What the singleton model needs to achieve
1. encapsulating a shared resource
2. provide a fixed instance creation method
3. provide a standard instance access interface
Creating a singleton pattern
This article takes the example of creating a Mysingletonclass singleton pattern. First, we need to define a class of Mysingletonclass.
[CPP]View Plaincopy
- @interface Mysingletonclass:nsobject {
- }
and add a class method for it (note that this is not an instance method)+ (ID) sharedinstance; a basic implementation is as follows:
static Mysingletonclass *sharedinstance = nil;
- + (mysingletonclass *) sharedinstance{
- @synchronized (self) {
- if (sharedinstance == nil) {
- sharedinstance = [[Mysingletonclass alloc]init];
- }
- }
- return sharedinstance;
- }  
In the above code (the keyword @synchronized is used to ensure that our singleton thread-level security can be applied in multithreaded mode. Thestatic variable sharedcldelegate is used to store a pointer to a singleton, and forcing all access to the variable must pass the class method + (ID) sharedinstance, on the + ( ID) Sharedinstance the creation of the instance the first time it is called. It is worth noting that the code above is [[Self class] alloc] instead of [Mysingletonclass alloc], which generally produces the same effect.
Control of the instantiation
In order to fully realize the uniqueness of the instance, it is necessary to avoid the instance being created multiple times by certain means. + (ID) sharedinstance controls the creation and access of the singleton, but does not control the code elsewhere to create more instances through the Alloc method, so we also overload any method that involves allocation, These methods include +new, +alloc,+allocwithzone:,-copywithzone:, and-mutablecopywithzone: Plus, + (ID) sharedinstance A minor modification is also required.
- + (ID) hiddenalloc
- {
- return [Super alloc];
- }
- + (ID) alloc
- {
- NSLog (@'%@: Use +sharedinstance instead of +alloc ', [[Self class] name];
- return nil;
- }
- + (ID)new
- {
- return [self alloc];
- }
- + (ID) Allocwithzone: (nszone*) zone
- {
- return [self alloc];
- }
- -(ID) Copywithzone: (Nszone *) zone
- { //-copy inherited from NSObject Calls-copywithzone:
- NSLog (@"Mysingletonclass:attempt to-copy may be a bug.");
- [Self retain];
- return self;
- }
- -(ID) Mutablecopywithzone: (Nszone *) zone
- {
- //-mutablecopy inherited from NSObject Calls-mutablecopywithzone:
- return [self copywithzone:zone];
- }
- + (ID) sharedinstance modified as follows:
- + (Mysingletonclass *) sharedinstance {
- @synchronized (self) {
- if (sharedcldelegate = = nil) {
- [[Self class] hiddenalloc] init]; //Assignment not do here
- }
- }
- return sharedcldelegate;
- }
If the subclass of the class is not considered,the +hiddenalloc method can be omitted. Since we are using [Self class] to implement dynamic recognition of the type, using [[Selfclass] hiddenalloc] can avoid calling to the overloaded Alloc method. In addition,Hiddenalloc provides an opportunity to invoke the original Alloc method for possible subclasses . The overloaded Alloc method above simply gives a log message and returns nil. The copying method simply increases the count of retain and does not return a new instance. This is also a manifestation of the nature of the singleton pattern, because technically, copying a single case is wrong (because it is a "singleton ") so in the Copywithzone method we give an error message, and of course we can throw a exception.
Single-Instance Destruction
usually we call the following method in the-(void) Applicationwillterminate: (uiapplication *) Application method:
- + (void) Attemptdealloc
- {
- if ([sharedcldelegate retaincount]! = 1)
- return;
- [Sharedcldelegate release];
- MyInstance = nil;
- }
It is worth noting that the above Attemptdealloc method, as its name implies, is simply trying to release the Singleton. If the count of retain is not 1, there are other places where retain messages have been sent to the single case . Consider that the lifetime of a singleton pattern is the end of the entire program. Therefore, there is no need to send a retain message to this single case anywhere in the program , even if the singleton is referenced. Instead of invoking the Sharedinstance method to refer to this singleton, it is safe to do so and is consistent with the technical implications of the Singleton pattern.
Here you need to set a parameter to manage memory manually.
the singleton mode app in iOS
There are several classes in IOS that use singleton patterns, such as NSApplication, Nsfontmanager, Nsdocumentcontroller,nshelpmanager, NSNull, Nsprocessinfo, Nsscriptexecutioncontext, nsuserdefaults.
- Official advice
- Since there is a certain risk in designing a single mode, the main consideration is the problem that may occur in multi-threaded situations, so Apple recommends using the following methods to achieve a single mode:
- static Mygizmoclass *sharedgizmomanager = nil;
- + (mygizmoclass*) Sharedmanager
- {
- @synchronized (self) {
- if (Sharedgizmomanager = = nil) {
- [[Self alloc] init]; Assignment not do here
- }
- }
- return sharedgizmomanager;
- }
- + (ID) Allocwithzone: (Nszone *) zone
- {
- @synchronized (self) {
- if (Sharedgizmomanager = = nil) {
- Sharedgizmomanager = [Super Allocwithzone:zone];
- return sharedgizmomanager; Assignment and return on first allocation
- }
- }
- return nil; On subsequent allocation attempts return nil
- }
- -(ID) Copywithzone: (Nszone *) zone
- {
- return self;
- }
- -(ID) retain
- {
- return self;
- }
- -(unsigned) retaincount
- {
- return Uint_max; Denotes an object, cannot be released
- }
- -(void) Release
- {
- Do nothing
- }
- -(ID) autorelease
- {
- return self;
- }
- Since the singleton mode basically conforms to the above design, when there are many classes to be designed into a singleton pattern, you can define
- A single template macro to improve the reuse of programs and reduce unnecessary errors.
- #define SYNTHESIZE_SINGLETON_FOR_CLASS (classname) \
- \
- static classname *shared# #classname = nil; \
- \
- + (classname *) shared# #classname \
- { \
- @synchronized (self) \
- { \
- if (shared# #classname = = nil) \
- { \
- shared# #classname = [[Self alloc] init]; \
- } \
- } \
- \
- return shared# #classname; \
- } \
- \
- + (ID) Allocwithzone: (nszone *) zone \
- { \
- @synchronized (self) \
- { \
- if (shared# #classname = = nil) \
- { \
- shared# #classname = [Super Allocwithzone:zone]; \
- return shared# #classname; \
- } \
- } \
- \
- Returnnil; \
- } \
- \
- -(ID) Copywithzone: (nszone *) zone \
- { \
- returnself; \
- } \
- \
- -(ID) retain \
- { \
- returnself; \
- } \
- \
- -(Nsuinteger) retaincount \
- { \
- return Nsuintegermax; \
- } \
- \
- -(void) release \
- { \
- } \
- \
- -(ID) autorelease \
- { \
- returnself; \
- }
Usage: Suppose the Apppreference class is to implement a single case
#import "AppPreference.h"
#import "SingletonTemplate.h"
@implementation Apppreference
Use the macro template to generate the code required for the singleton
Synthesize_singleton_for_class (apppreference)
This is a test method
+ (void) Test {
Use a single case
Apppreference *apppreference = [Apppreference sharedapppreference];
}
@end
IOS single case (Singleton) Summary and third Library Reference Singleton