#import "XMGTool.h"/** * 1:arc The Complete single example: Alloc internal call + (Instancetype) Allocwithzone: (struct _nszone *) Zone method, so override the method, with GCD one-time function, The default is thread-safe add a lock, you can also lock @synchronized (self) {if (_instance = = nil) {_instance = [super Allocwithzone:zone];}} 2: Also consider the copy and mutablecopy two cases, to rewrite two methods, you must first comply with two protocols: <nscopying, nsmutablecopying> protocol, directly return an instance can be, Where the object calls copy: Regardless of the variable immutable copy of the object is immutable, if the source object is immutable, copy returns the source object, the source object reference count plus 1, and copy the value of the source object, if the source object is mutable, it will produce a new object, the new object reference count plus 1, Mutablecopy, the copied objects are mutable, are also new objects, the new object reference count plus 1, as long as the new object is generated is a deep copy, no new objects, only copy the pointer is a shallow copy 3: The object calls the new method to create the object, it is equivalent to call the Alloc Object created by the Init method*/@implementationXmgtool//0. Provide global variablesStaticXmgtool *_instance;//1.alloc-->allocwithzone+ (Instancetype) Allocwithzone: (struct_nszone *) zone{//add mutex to solve multi-threaded access security issues//@synchronized (self) {//if (_instance = = nil) {//_instance = [Super Allocwithzone:zone];// }// } //is thread-safe in itself. Staticdispatch_once_t Oncetoken; Dispatch_once (&oncetoken, ^{_instance=[Super Allocwithzone:zone]; }); return_instance;}//2. Providing class methods+(instancetype) sharetool{return[[Self alloc]init];}//3. Rigorous-(ID) Copywithzone: (Nszone *) zone{return_instance;}-(ID) Mutablecopywithzone: (Nszone *) zone{return_instance;}@end
2:mrc
#import "XMGTool.h"/** * MRC next Single implementation: 1: Need to rewrite the release method, do nothing, because do not need to release operation 2:retain will produce a new object operation will make the reference count plus 1, this time return a created instance, 3: Override the Retaincount method, Returns a maximum value*/@implementationXmgtool//Modify the environment for MRC//0. Provide global variablesStaticXmgtool *_instance;//1.alloc-->allocwithzone+ (Instancetype) Allocwithzone: (struct_nszone *) zone{//add mutex to solve multi-threaded access security issues//@synchronized (self) {//if (_instance = = nil) {//_instance = [Super Allocwithzone:zone];// }// } //is thread-safe in itself. Staticdispatch_once_t Oncetoken; Dispatch_once (&oncetoken, ^{_instance=[Super Allocwithzone:zone]; }); return_instance;}//2. Providing class methods+(instancetype) sharetool{return[[Self alloc]init];}//3. Rigorous-(ID) Copywithzone: (Nszone *) zone{return_instance;}-(ID) Mutablecopywithzone: (Nszone *) zone{return_instance;}#if__has_feature (OBJC_ARC)//condition satisfies ARC#else//MRC-(OneWayvoid) release{}-(instancetype) retain{return_instance;}//Habits-(Nsuinteger) retaincount{returnmaxfloat;}#endif@end
3: Generic macro definition:
#defineSingleh (name) + (instancetype) share# #name;#if__has_feature (OBJC_ARC)//condition satisfies ARC#defineSinglem (name) static ID _instance;+ (instancetype) Allocwithzone: (struct_nszone *) zone{Staticdispatch_once_t oncetoken;dispatch_once (&oncetoken, ^{_instance=[Super Allocwithzone:zone];});return_instance;}+(instancetype) share# #name {return[[Self alloc]init];}-(ID) Copywithzone: (Nszone *) zone{return_instance;}-(ID) Mutablecopywithzone: (Nszone *) zone{return_instance;}#else//MRC#defineSinglem (name) static ID _instance;+ (instancetype) Allocwithzone: (struct_nszone *) zone{Staticdispatch_once_t oncetoken;dispatch_once (&oncetoken, ^{_instance=[Super Allocwithzone:zone];});return_instance;}+(instancetype) share# #name {return[[Self alloc]init];}-(ID) Copywithzone: (Nszone *) zone{return_instance;}-(ID) Mutablecopywithzone: (Nszone *) zone{return_instance;}-(OneWayvoid) release{}-(instancetype) retain{return_instance;}-(Nsuinteger) retaincount{returnmaxfloat;}#endif
"' OBJC
The main differences between concurrent queues and global concurrent queues created using the Crearte function:
1. Global concurrent queues are inherently default throughout the application, and for a total of four concurrent queues with high priority, default priority, low priority, and background priority, we just choose one of them to use directly. And the Crearte function is real deal to create a queue from the beginning.
2. Prior to iOS6.0, all functions with the Create and retain in GCD are required to do a release operation at the end. The home row and global concurrent queues do not require us to release manually. Of course, after iOS6.0 GCD has been incorporated into the ARC memory management category, even objects created with the retain or create function are no longer required to be manually released by the developer, and we treat the GCD as if the normal OC object is OK.
3. When using the fence function, Apple officially specifies that the fence function is only valid when used with a concurrent queue created by the CREATE function itself (no specific reason given)
4. Other differences involve system-level threading programming of the XNU kernel, not listed.
5. Give some references (you can study it yourself):
gcdapi:https://developer.apple.com/library/ios/documentation/performance/reference/gcd_libdispatch_ref/ Index.html#//apple_ref/c/func/dispatch_queue_create
Libdispatch version Source: http://www.opensource.apple.com/source/libdispatch/libdispatch-187.5/
```
# # #1. Singleton mode
-1.1 Concept-related
(1) Single case mode
There is only one instance of a class during program run
(2) Use occasions
Share a single resource throughout the application (this resource only needs to be initialized 1 times)
-1.2 Arc Implementation single case
(1) Steps
01 provides a static modified global variable inside the class
02 provides a class method for easy access to the outside world
03 overriding the +allocwithzone method to ensure that only one memory space is allocated once for a single object
04 for Rigor, rewrite the-copywithzone method and the-mutablecopywithzone method
(2) Related code
"' OBJC
Provides a static modified global variable that strongly references an instance of a singleton object that has already been instantiated
Static Xmgtools *_instance;
Class method, returning a singleton object
+ (Instancetype) sharetools
{
Note: It is recommended to use self instead of using the class name tools directly (consider inheritance)
return [[Self alloc]init];
}
Guaranteed to allocate only one storage space at a time
+ (Instancetype) Allocwithzone: (struct _nszone *) zone
{
Using one-time code in GCD
Static dispatch_once_t Oncetoken;
Dispatch_once (&oncetoken, ^{
_instance = [Super Allocwithzone:zone];
// });
Use lock to ensure that only one storage space is allocated
@synchronized (self) {
if (_instance = = nil) {
_instance = [Super Allocwithzone:zone];
}
}
return _instance;
}
/*
1. Mutablecopy creates a new mutable object and initializes it to the value of the original object, and the reference count for the new object is 1;
2. Copy returns an immutable object. In two cases: (1) The Wakahara object is an immutable object, then the original object is returned, and its reference count is added 1, and (2) The Wakahara object is a mutable object, then a new immutable object is created and initialized to the value of the original object, and the reference count of the new object is 1.
*/
Make the code more rigorous
-(nonnull ID) Copywithzone: (Nullable Nszone *) zone
{
return [[Self class] allocwithzone:zone];
return _instance;
}
-(nonnull ID) Mutablecopywithzone: (Nullable Nszone *) zone
{
return _instance;
}
```
-1.3 MRC Implementation single case
(1) Implementation steps
01 provides a static modified global variable inside the class
02 provides a class method for easy access to the outside world
03 overriding the +allocwithzone method to ensure that only one memory space is allocated once for a single object
04 for Rigor, rewrite the-copywithzone method and the-mutablecopywithzone method
05 overriding the Release method
06 overriding the Retain method
07 We recommend that you return a maximum value in the Retaincount method
(2) Configuring MRC Environment Knowledge
01 Note that arc is not a garbage collection mechanism, it is a compiler feature
02 Configuring the MRC Environment: Build setting Search automatic ref-> Modify to No
(3) Related code
"' OBJC
Provides a static modified global variable that strongly references an instance of a singleton object that has already been instantiated
Static Xmgtools *_instance;
Class method, returning a singleton object
+ (Instancetype) sharetools
{
Note: It is recommended to use self instead of using the class name tools directly (consider inheritance)
return [[Self alloc]init];
}
Guaranteed to allocate only one storage space at a time
+ (Instancetype) Allocwithzone: (struct _nszone *) zone
{
Using one-time code in GCD
Static dispatch_once_t Oncetoken;
Dispatch_once (&oncetoken, ^{
_instance = [Super Allocwithzone:zone];
// });
Use lock to ensure that only one storage space is allocated
@synchronized (self) {
if (_instance = = nil) {
_instance = [Super Allocwithzone:zone];
}
}
return _instance;
}
Make the code more rigorous
-(nonnull ID) Copywithzone: (Nullable Nszone *) zone
{
return [[Self class] allocwithzone:zone];
return _instance;
}
-(nonnull ID) Mutablecopywithzone: (Nullable Nszone *) zone
{
return _instance;
}
In the MRC environment, if the user retain once, then directly return the instance variable, not the reference counter +1
If the user is released one time, then nothing is done, because the singleton mode in the entire program running process has only one copy, the program exits after the release, so do not need to operate on the reference counter
-(OneWay void) release
{
}
-(Instancetype) retain
{
return _instance;
}
Idiomatic, experienced programmers print Retaincount This value can be guessed that this is a singleton
-(Nsuinteger) Retaincount
{
return maxfloat;
}
```
-1.4 Generic version
(1) An interesting conversation
01 Q: Is writing a single sample code applicable in both ARC and MRC environments?
Answer: You can use conditional compilation to determine whether the current project environment is arc or MRC
02 Q: What is the code for conditional compilation?
"' OBJC
Answer: Conditional compilation
#if __has_feature (OBJC_ARC)
If it's arc, then execute the code here 1.
#else
If it is not arc, then execute the Agent code 2
#endif
```
03 Q: In the project often need to implement a lot of singleton, such as download, network requests, music playback and so on, weak weak Ask a single case can be inherited?
A: Single example is not allowed to inherit, if you want to write at once, around the use, then recommend the Pro use with parameters of the macro definition!
04 Q: How does the macro definition get done?
A: Well, look back at my code, pro.
(2) Use a macro with parameters to complete the common version of the single mode code
01 Note Conditional compilation code cannot be included in the macro definition
02 macro-defined code only needs to be written once, and then dragged directly into the project with OK
iOS develops the complete notation and generic macro definitions for arc and MRC under single example