OS x memory management: source code analysis (1). OS Memory Management
After learning Objective-C advanced programming, let's summarize it.
In Objective-C memory management, autorelease is automatically released, which looks like ARC, right? However, it is not. In fact, it is a bit like we used to learn local variables in C language.
Implementation of GNUstep
Let's take a closer look at the implementation principles of autorelease. Since the NSObject Foundation framework is not open-source, we will study the GNUstep open-source software.
First look at a source code
[obj autorelease]
The source code actually calls the autorelease method of the NSObject class.
-(id)autorelease{ [NSAutoreleasePool addObject:self];}
From the above code, we can analyze it. In fact, autorelease actually calls the addObject method in the NSAID utoreleasepool.
After reading the above content, we need to discuss in detail the implementation principle of the NSAID utoreleasepool. The following is the source code of my summary. because the implementation of the source code of the nutoreleasepool is too complicated, the source code here is simplified.
NSAID utoreleasepool. m addObject
+ (Void) addObject :( id) anObj {ngutoreleasepool * pool = obtain the NSAID utoreleasepool we are using; if (pool! = Nil) {[pool addObject: anObj];} else {NSLog (@ "nutoreleasepool object does not exist ");}}
The addObject class method calls the addObject of the nsaid utoreleasepool object in use. This sentence may be difficult to understand. It doesn't matter. Next, let's look at a set of source code.
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];id obj = [[NSObject alloc] init];[obj autorelease];
From the code above, we can see that if the pool variable is assigned, it is the instantiated object that is using the NSAID utoreleasepool.
In my learning process, I also saw another nested method.
NSAutoreleasePool *pool0 = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; id obj = [[NSObject alloc] init]; [obj autorelease]; [pool2 drain]; [pool1 drain];[pool0 drain];
In this nested structure, pool2 is the object used by the NSAID utoreleasepool, and follows the principle of using the most tested object.
Let's take a look at the implementation principle of addObject. Actually, the addObject method of array is called.
-(void)addObject :(id)anObj{ [array addObject : anObj];}
The above is the GNUstep implementation. In fact, GNUstep uses the connection list, which is the same as the append principle in the NSNutableArray object. That is to say, if we call the autorelease method, the object that calls the autorelease method will be appended to the array of the NSAID utoreleasepool.
[pool drain];
You can use drain to delete objects that are using the NSAID utoreleasepool.
Let's take a look at the implementation principle of drain.
-(void)drain{ for(id obj in array){ [obj release]; } [array release];}
Each cycle calls the release method to release the SDK.
Apple's implementation
The following describes how autorelease is implemented in the objc4 library.
Class AutoreleasePoolPage {static inline void * push () {// generate NSAID eleasepool here} static inline void * pop () {// discard NSAID utoreleasepool class Object releaseAll ();} static inline id autorelease (id obj) {// here, it is equivalent to the addObject method of the classes Class; * AutoreleasePoolPage = get the object using the autoreleasePoolPage class; AutoreleasePoolPage-> add (obj );} id * add (id obj) {// The lecture object is appended to the array} void releaseAll () {// call rel Producer instance} void * obj _ autoreleasePoolPush (void) {return autoreleasePoolPage: push ();} void * obj _ autoreleasePoolPop (void) {return autoreleasePoolPage :: pop (void * ctxt);} void * obj _ autorelease (id obj) {return autoreleasePoolPage: autorelease (obj);} Although c ++ contains dynamic arrays similar to NSNutableArray, however, the behavior is completely different from the implementation of GNUstep.
First, let's take a look at the running process of the NSAID utoreleasepool and autorelease methods. And the relationship with the object from the slave c ++
NSAID utoreleasepool * pool = [[NSAID utoreleasepool alloc] init]; // equivalent to obj _ autoreleasePoolPush () id obj = [[NSObject alloc] init]; [obj autorelease]; // equivalent to * obj _ autorelease (obj) [pool drain]; // equivalent to * obj _ autoreleasePoolPop (pool)
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.