http://www.justinyan.me/post/1306
First, the origin of the problem
Everything stems from the Apple's official documentation on the singleton (Singleton) demo code: Creating a Singleton Instance.
The main controversy is concentrated in the following paragraph:
Static MyGizmoClass *sharedGizmoManager = nil;
+ (MyGizmoClass*)sharedManager
{
If (sharedGizmoManager == nil) {
sharedGizmoManager = [[super allocWithZone:NULL] init];
}
Return sharedGizmoManager;
}
+ (id)allocWithZone:(NSZone *)zone
{
Return [[self sharedManager] retain];
}
among them:
sharedGizmoManager = [[super allocWithZone:NULL] init];
There is another version of this paragraph, instead of using allocWithZone but directly alloc, as follows:
sharedGizmoManager = [[super alloc] init];
This raises a discussion, why should we override the allocWithZone method, what is the difference between alloc and allocWithZone?
PS: Regarding the implementation of the ObjC singleton, this blog post by @Venj has a more detailed discussion, including thread safety considerations. Interested children's shoes can be watched.
Second, Allocwithzone
First we know that we need to make sure that there is only one instance of the Singleton class, and when we initialize an object, [[Class alloc] init] actually does two things. Alloc allocates memory space to an object, Init is the initialization of the object, including setting the initial value of the member variable. In addition to the Alloc method, there is another way to allocate space to the object: Allocwithzone.
In the official document of the NSObject class, the Allocwithzone method describes that the parameters of the method are ignored, and the correct procedure is to pass nil or null parameters to it. The reason why this method exists is a legacy of history.
Do not override allocwithzone:to include any initialization code. Instead, class-specific versions of Init ... methods.
This method is exists for historical reasons; Memory zones is no longer used by objective-c.
It is mentioned in the document that the memory zone has been deprecated, only for historical reasons to retain this interface. I didn't find out what the historical reason was, but the content of the introduction would be a little more involved.
The practice proves that when initializing an instance of a class using the Alloc method, the default is to call the Allocwithzone method. The reason for overwriting the Allocwithzone method is obvious: to keep the singleton instance unique, you need to overwrite all methods that generate a new instance, and if someone initializes the singleton class without walking [[Class alloc] init], it is directly Allocwithzone, then this single case is no longer a singleton, so it is necessary to plug the method. Allocwithzone's answer to this is solved, but the problem is endless.
Here's another question: What's the hell is Memory Zone?
Third, Nszone
Apple's official document is a few simple sentences, it is very:
NSZone
Used to identify and manage memory zones.
Typedef struct _NSZone NSZone;
Availability
Available in OS X v10.0 and later.
Declared In
NSZone.h
CocaDev's wiki is written in more detail, the original address is here: http://cocoadev.com/wiki/NSZone
In general, NSZone is a way for Apple to allocate and free memory. It is not an object. Instead, it uses the C structure to store information about the object's memory management. Basically, the developer does not need to pay attention to this thing. The cocoa Application uses a system default NSZone to manage the application objects. So when do you want to have a NSZone of your own control? When the default NSZone manages a large number of objects. At this time, the release of a large number of objects may lead to severe fragmentation of memory, cocoa itself has been optimized, every time you allocate alloc will try to fill the gaps in memory, but the time is too expensive. So, you can create an NSZone yourself, so that when you have a large number of alloc requests, all of them are transferred to the specified NSZone, reducing the amount of time overhead. Moreover, using NSZone can also remove all the things in the zone you created, saving a lot of time to go to a dealloc object.
In general, when you need to create a large number of objects, using NSZone can save you some time, but only if you know how to use it. This wiki also writes about the usage of NSZone. Interested children's shoes can be seen, but another 2002 article says that developers can't create a real NSZone (it seems that this is historical reason). Only one child zone of the main zone can be created. The article is here: http://www.cocoabuilder.com/archive/cocoa/65056-what-an-nszone.html#65056 Timothy J.wood's answer.
Timothy also said that if NSZone is available, multiple objects can reduce paging at the same time, and dealloc can reduce memory fragmentation at the same time. Presumably, Apple has dealt with this aspect, and it is transparent to developers, and developers do not need to do it themselves.
Iv. Conclusion
Allocwithzone is not encouraged by Apple, and most of the time programmers do not need to manage their own zone. Of course it's always nice to know more about something.
From Alloc and Allocwithzone in Objective-c.