When I was a beginner at objectice-C, I always felt confused about the memory management mechanism of objective-C. The program often experienced memory leaks or inexplicable crashes. I have summarized my research achievements and experience on the objective-C memory management mechanism, and wrote such a simple tutorial. I hope it will be helpful to you and you are welcome to discuss it together. The memory management involved in this article is for Classes inherited from NSObject. I. Basic Principle Objective-C memory management mechanism and. net/Java, the fully automatic garbage collection mechanism, is different. It is essentially a manual management method in C language, but it only adds some automatic methods. 1. The Objective-C object is generated on the heap. After being generated, a pointer is required to point to it. ClassA * obj1 = [[ClassA alloc] init]; 2 Objective-C objects will not be automatically destroyed after use. You need to execute dealloc to release space (destroy); otherwise, the memory will be leaked. [Obj1 dealloc]; this brings about a problem. In the following code, does obj2 need to call dealloc? ClassA * obj1 = [[ClassA alloc] init]; ClassA * obj2 = obj1; [obj1 hello]; // output hello [obj1 dealloc]; [obj2 hello]; // can this row and the next row be executed? [Obj2 dealloc]; no, because obj1 and obj2 are just pointers and they point to the same object. [obj1 dealloc] has destroyed this object, you cannot call [obj2 hello] or [obj2 dealloc]. Obj2 is actually an invalid pointer. How to Avoid invalid pointers? See the next one. 3 Objective-C uses the reference count (ref count or retain count ). The number of times the object is referenced. For example, if an object is pointed to (referenced) by two pointers, its retain count is 2. To destroy an object, call release instead of dealloc. Release will reduce retain count by 1. Only when retain count is equal to 0 will the system call dealloc to actually destroy this object. ClassA * obj1 = [[ClassA alloc] init]; // when an object is generated, retain count = 1 [obj1 release]; // release reduces retain count by 1, retain count = 0, dealloc is automatically called, and the object is destroyed. Let's look back at the problem with the Invalid Pointer. Is it solved by changing dealloc to release? ClassA * obj1 = [[ClassA alloc] init]; // retain count = 1 ClassA * obj2 = obj1; // retain count = 1 [obj1 hello]; // output hello [obj1 release]; // retain count = 0, after the object is destroyed [obj2 hello]; [obj2 release]; [obj1 release, obj2 is still an invalid pointer. The problem persists. For the solution, see the next one. 4 when the Objective-C pointer is assigned a value, retain count will not be automatically added and manual retain is required. ClassA * obj1 = [[ClassA alloc] init]; // retain count = 1 ClassA * obj2 = obj1; // retain count = 1 [obj2 retain]; // retain count = 2 [obj1 hello]; // output hello [obj1 release]; // retain count = 2-1 = 1 [obj2 hello]; // output hello [obj2 release]; // retain count = 0. The object is destroyed! NOTE: If [obj2 release] is not called, The retain count of this object is always 1 and will not be destroyed, causing memory leakage. (1-4 can refer to the example program memman-no-pool.m in the attachment) It does not leak memory, but it seems a little troublesome, there is no simple way? See the next one. 5. The autorelease pool (automatically released Object pool) is introduced in Objective-C. objects can be automatically released when some rules are followed. (Autorelease pool is still not the fully automated garbage collection mechanism of. Net/Java.) for newly generated objects in 5.1, you only need to call autorelease, and you do not need to call release any more! ClassA * obj1 = [[ClassA alloc] init] autorelease]; // retain count = 1 but you do not need to call release 5.2. The code is similar to the previous code for pointer assignment. ClassA * obj1 = [[ClassA alloc] init] autorelease]; // retain count = 1 ClassA * obj2 = obj1; // retain count = 1 [obj2 retain]; // retain count = 2 [obj1 hello]; // output hello // For obj1, you do not need to call (actually cannot call) release [obj2 hello]; // output hello [obj2 release]; // retain count = 2-1 = 1 careful readers will surely find that this object has not been destroyed. When will it be destroyed? Who will destroy it? (Refer to the example program memman-with-pool.m in the attachment) see the next one. 6 autorelease pool principle analysis. (In fact, it is very simple. You must stick to it. Otherwise, you still cannot understand the Objective-C memory management mechanism .) 6.1 autorelease pool is not born and needs to be created manually. Only when you create an iphone project, xcode will automatically help you write it. The real name of autoreleasepool is NSAID utoreleasepool. NSMutableArray is used to save all objects declared as autorelease. If an object is declared as autorelease, the system will add this object to this array. ClassA * obj1 = [[ClassA alloc] init] autorelease]; // retain count = 1. Add this object to the autorelease pool. When the 6.3 nutoreleasepool itself is destroyed, it traverses this array and each member in the release array. If the retain count of the members in the array is 1 at this time, after release, the retain count is 0, and the object is destroyed. If the retain count of the members in the array is greater than 1 at this time, the retain count is greater than 0 after release, and the object is still not destroyed, causing memory leakage. 6.4 by default, there is only one autorelease pool, which is usually similar to the following example. Int main (int argc, const char * argv []) {NSAID utoreleasepool * pool; pool = [[NSAID utoreleasepool alloc] init]; // do something [pool release]; return (0);} // all objects marked as autorelease in main are destroyed only when the pool is destroyed. If you have a large number of objects marked as autorelease, this obviously cannot make good use of the memory, it is very easy to cause insufficient memory in iphone memory-constrained programs. For example: int main (int argc, const char * argv []) {ngutoreleasepool * pool = [[ngutoreleasepool alloc] init]; int I, j; for (I = 0; I <100; I ++) {for (j = 0; j <100000; j ++) [NSString stringWithFormat: @ "1234567890"]; // The generated object is autorelease.} [Pool release]; return (0);} // main (you can refer to the example program memman-many-objs-one-pool.m in the attachment, through the monitoring tool at runtime you can find that there is a sharp increase in use, it is not released until the pool is destroyed.) You need to consider the next one. 7. Multiple autorelease pools can be nested in the Objective-C program. When you need to create a large number of local variables, you can create an embedded autorelease pool to release the memory in time. (Thanks to hhyytt and neogui, in some cases, the system will automatically create the autorelease pool. See chapter 4) int main (int argc, const char * argv []) {NSAID utoreleasepool * pool = [[NSAID utoreleasepool alloc] init]; int I, j; for (I = 0; I <100; I ++) {NSAID utoreleasepool * loopPool = [[NSAID utoreleasepool alloc] init]; for (j = 0; j <100000; j ++) [NSString stringWithFormat: @ "1234567890"]; // The generated object is autorelease. [LoopPool release];} [pool release]; return (0);} // main (you can refer to the example program memman-many-objs-many-pools.m in the attachment, memory usage changes are minimal)