Cat Share, must boutique
Original articles, welcome reprint. Reprint Please specify: Sanayu's Blog
Address: http://blog.csdn.net/u013357243?viewmode=contents
Singleton Mode 1: The role of a singleton pattern
You can guarantee that there is only one instance of a class when the program is running, and that the instance is easy for outside access
Thus conveniently control the number of instances, and save system resources
The use of single-case mode
Share a single resource throughout the application (this resource only needs to be initialized 1 times)
In short, I made a tool class, he has a copy, such as I designed a music player Nyplayer, this player class I think he has a, this is a single case, I use when I only need to let the player work, if more than I do not know the designation that, or there will be a repetition of the bug.
Baidu Encyclopedia is said: The singleton mode is a commonly used software design mode. In its core structure, it contains only a special class called a singleton class. The singleton mode can ensure that there is only one instance of a class in the system, and the instance is easy to be accessed by the outside world, thus it is convenient to control the number of instances and save system resources. Singleton mode is the best solution if you want to have only one object for a class in the system.
Simply put, there is only one object in a class.
2:ARC, the realization of singleton pattern
Process:
Keep an instance of global static in. m
Here to use static, remember him, later I write a blog about static keywords.
staticid _instance;
Override Allocwithzone: Method, create a unique instance here (Note thread safety)
When you call the [class name Alloc] method when you create the class, the internal automatically calls the Allcwithzone method to load a space, so we just rewrite this method, and when we define a global variable instance it's worth it, it will return directly, if not, the parent class method will be called [ Super Allocwithzone:zone] and assigned to instance, but at this point there is a danger, that is, if there are two threads all come in, that will be allocated two times, so we have to lock this section of the program.
+ (id)allocWithZone:(struct _NSZone *)zone { ifnil// 防止频繁加锁 @synchronized(self) { ifnil// 防止创建多次 _instance = [super allocWithZone:zone]; } } } return _instance;}
Provides a class method for the outside world to access a unique instance.
Like the allocwithzone above, the difference is that the "[Self alloc] init" method is called here.
+ (instancetype)sharedMusicTool { ifnil// 防止频繁加锁 @synchronized(self) { ifnil// 防止创建多次 _instance = [[self alloc] init]; } } } return _instance;}实现copyWithZone:方法- (id)copyWithZone:(struct _NSZone *)zone { return _instance;}
A singleton pattern in 3:MRC
Process:
Non-arc (MRC), single-instance mode implementation (several steps more than ARC)
Implement memory management methods.
- (id)retain { return self; }//父类里面是计数器+1,重写将不会+1- (NSUInteger)retainCount { return 1; }//父类里面返回当前对象的计数个数- (oneway void)release {}//父类里面是计数器-1,重写将不会-1- (id)autorelease { return self; }//父类里面内存自动管理释放的,跟内存池有关
GCD Perfect Single-case mode (ARC&MRC-All) to judge the ARC's macro
The first thing to know here is a macro __has_feature (OBJC_ARC)
The singleton pattern is different in the ARC\MRC environment, it needs to write 2 different sets of code
You can use a macro to determine whether an arc environment.
#if __has_feature(objc_arc)// ARC#else// MRC#endif
Value-Passed macros
Just one sentence.
#define NYSingletonH(name) + (instancetype)shared##name;
When it is used, it is automatically replaced by the name.
Run the code once with GDC to solve
How to solve it? It's actually a one-time code for GCD.
The code is as follows:
+(id)allocWithZone:(struct _NSZone *)zone { ifnil) { staticdispatch_once_t onceToken; dispatch_once(&onceToken, ^{ ifnil) { _instance = [super allocWithZone:zone]; } }); } return _instance; }
Shortcut, in Xcode as long as the knock Dispatch_once will automatically have, fill fill write.
The ultimate way, after a single example does not have to knock the code, directly dropped on the line.
The first step, resume A. h file, for example
In the second step, the following code is written to the file:
. h file#Define NYSINGLETONH (name) + (instancetype) shared##name;//. m file#Define Nysingletonm#If __has_feature (OBJC_ARC)#Define NYSINGLETONM (name)Static ID _instance;+ (ID) allocwithzone: (struct _nszone *) zone {if (_instance = = nil){Static dispatch_once_t Oncetoken;Dispatch_once (&Oncetoken, ^{if (_instance = = nil){_instance =[Super Allocwithzone:zone]; } }); }return _instance; }+ (Instancetype) gkfx##Name {if (_instance = = nil){Static dispatch_once_t Oncetoken;Dispatch_once (&Oncetoken, ^{if (_instance = = nil){_instance =[[Self alloc]Init]; } }); }return _instance; }-(ID) Copywithzone: (Nszone *) zone {return _instance;\\ }#Else#Define NYSINGLETONM (name)Static ID _instance;+ (ID) allocwithzone: (struct _nszone *) zone {if (_instance = = nil){Static dispatch_once_t Oncetoken;Dispatch_once (&Oncetoken, ^{if (_instance = = nil){_instance =[Super Allocwithzone:zone]; } }); }return _instance; }+ (Instancetype) gkfx##Name {if (_instance = = nil){Static dispatch_once_t Oncetoken;Dispatch_once (&Oncetoken, ^{if (_instance = = nil){_instance =[[Self alloc]Init]; } }); }return _instance; }-(ID) Copywithzone: (Nszone *) zone {return _instance; }-(ID) retain {return self; }-(Nsuinteger) Retaincount{return 1;}-(OneWay void) release{}-(ID) autorelease{return self;}#endif
The \ symbol is to let the following east side to the previous line, because define can only define one row.
Step three: Write the calling code in the PCH file:
#import "NYSingleton.h"
Fourth step: Call in the class you need to use:
Call this in the point H file
Call this in the point m file
Last Call, or singleton:
Supplement, custom Macros replace NSLog
Note: In the development process, the use of NSLog to print information for debugging, but the Releae software can not contain nslog, there may be a risk of being called back, but if all the comments out nslog that too painful, it is not conducive to future debugging.
Below, we can use a custom macro to replace the NSLog, only when we want to output
/* XCode LLVM XXX - Preprocessing中Debug会添加 DEBUG=1 标志 */#ifdef DEBUG#define NSLog(FORMAT, ...) fprintf(stderr,"%s:%d\t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);#else#define NSLog(FORMAT, ...) nil#endif
Paste the above code into the projectname-prefix.pch file.
When debugging, the output (format: File name: line number) of the log.
When the release is released, the log output is turned off.
Because the DEBUG in Xcode LLVM xxx-preprocessing adds the debug=1 flag. Of course, we can also change the debug directly into a digital set.
Cat learn iOS (52) A single example design mode of multi-threaded network GCD