In this blog post, we will introduce how to use memory management in OBJECTIVE-C. When a program runs, it does not release unused space memory when it is not in time. Then, the program will become more and more bloated, memory consumption will continue to rise. When we use it, we feel a lot of cards, eventually making the program run. Therefore, it is necessary to dispose of invalid memory in a timely manner.
How does an object experience a process when it is initially created and released to the last collection?
Includes: birth (implemented by Alloc or New method), survival (receiving messages and performing actions), making friends (by compounding and passing parameters to methods), eventually dying (released).
One, reference counting
At the time of object creation, cocoa used a technique called reference counting :
1) When an object is accessed , the value of the reference counter is incremented by 1, and a retain message can be sent to the object;
2) When the object's access is closed , the value of the reference counter is reduced by 1, and a release message can be sent to the object;
3) When the value of the reference counter is 0 , which means that the object is no longer accessed, the system memory it consumes will be recycled , automatically sending an dealloc message to the object, and will generally override the Dealloc method ;
4) to get the current value of the hold counter, you can send a retaincount message .
Below, we describe the following methods of Declaration and implementation:
First, create a new Retaintracker class, modify the declaration file for the class, and implement the method:
RetainTracker.h#import <Foundation/Foundation.h>@interface retaintracker:nsobject 6-(ID) retain; void) release; 8-(Nsuinteger) retaincount; @end
1Retaintracker.m23#import"RetainTracker.h"45@implementationRetaintracker6-(Id) Init7{8if (self = =[Super Init])9{Ten NSLog (@"Init:retain Count of%lu.", [self retaincount]);11}12 return13 }14 15-(void) Dealloc16 {< Span style= "color: #008080;" >17 NSLog (@ "dealloc called. byebye! "); 18 [Super Dealloc];}20 21 @end
Then call the Retain,release,retaincount,dealloc method in the MAIN.M main function:
1#import <Foundation/Foundation.h>2#import"RetainTracker.h"34int main (int argc,Constchar *Argv[])5{6 Retaintracker *tracker = [RetaintrackerNEW];//Count =178[Tracker retain];9 NSLog (@"Retaincount:%lu", [tracker Retaincount]);//Count =21011[Tracker retain];NSLog (@"Retaincount:%lu", [tracker Retaincount]);//Count =31314[Tracker release];NSLog (@"Retaincount:%lu", [tracker Retaincount]);//Count =21617[Tracker release];NSLog (@"Retaincount:%lu", [tracker Retaincount]);//Count =11920[Tracker retain];NSLog (@"Retaincount:%lu", [tracker Retaincount]);// count =2 [tracker release]; NSLog (@ "retaincount:%lu", [tracker Retaincount]); count =1 [tracker release]; Count =0, dealloc return (0); }
The results of the operation are as follows:
Second, automatic release
We all know that when the object is no longer used, it should be released in time. But in some cases it's not easy to figure out when to stop using an object. It would be nice if I could release it automatically. Fortunately, there is an automatic release pool (autorelease) in cocoa. Careful friends can find that, after iOS5, each new project, in the main function, there is a @autoreleasepool method, which is the execution of the code is added to the automatic release pool.
The NSObject class provides a method called autorelease :
1-(ID) autorelease;
This method pre-sets a release message that will be sent at some time in the future. When sending an autorelease message to an object, the object is actually added to the auto-free pool. When the auto-free pool is destroyed, a release message is sent to all objects in the pool.
So, next, we'll use the method of adding to the auto-release pool to modify the example above. The contents of the Retaincount class do not change, as long as the contents of the main function are modified:
1/*Use Auto Release pool*/2int main (int argc,Constchar *Argv[])3{4 NSAutoreleasePool *Pool5 Pool =[[NSAutoreleasePool alloc] init];67 Retaintracker *tracker = [RetaintrackerNEW];//Count =18 NSLog (@"After new, tracker:%lu", [tracker Retaincount]);//Count =1910[Tracker retain];NSLog (@"After retain, tracker:%lu", [tracker Retaincount]);//Count =212[Tracker Autorelease];NSLog (@"After Autorelease, tracker:%lu", [tracker Retaincount]);//Count =21415[Tracker release];NSLog (@"After release, tracker:%lu", [tracker Retaincount]);//Count =1NSLog (@"Releasing pool");18[Pool release];Destroying an auto-release pool1920@autoreleasepool {Retaintracker *Tracker2;Tracker2 = [RetaintrackerNEW];//Count = 123 [Tracker2 retain]; //count =224 [Tracker2 Autorelease]; // count still = 225 Span style= "color: #000000;" > [Tracker2 release]; //count = 126 NSLog (@ " Span style= "color: #800000;" >auto releasing pool. "); 27 }28 29 return (030}
Operation Result:
The Tracker object, which is added to the auto-free pool through the autorelease message. When the pool auto-release cell sends the release message, the pool object's reference counter has a value of 0, and the Dealloc method is called to be destroyed. Causes objects in the auto-release pool to be destroyed along with them.
Three, memory management rules
Next, we will introduce several rules of memory management for cocoa.
1). When you use the new, Alloc, copy method to create an object, the value of the object's hold counter is 1;
When not in use, send a release or autorelease message to destroy the object.
1 Nsmutablearray *array; count =1//Use thearray4 [array release]; Dealloc, Count =0
2). When you obtain an object by another method, assuming that the value of the object's retention counter is 1 and has been set to be automatically freed, you do not need to do anything to clean up the object.
1 Nsmutablearray *array; 2 array = [Nsmutablearray arraywithcapacity:///count =1, autorelease; Use the array
3). The time for the automatic release of the pool to be destroyed is completely deterministic and will not be destroyed during the cyclic phase. If a loop is to be added to the auto-free pool of objects in many cases, consider a partial release of the loop before creating a new auto-release pool. This ensures that the allocation and destruction of the automatic free pool is as small as possible.
1 NSAutoreleasePool *Pool2 Pool =[[NSAutoreleasePool alloc] init];3IntI4for (i=0; i<100000; i++)5{6IdObject =[Somearray objectatindex:i];object descrption]; 8 If (I%100 = = 0) {10 // emptied 100 times per loop, then creates a new auto-free pool 11 [pool release]; 12 pool = [[Nsautoreleaasepool Alloc]init];13 }14 }15 [Pool release];
4). Automatic reference count (auto Reference counting, i.e.arc), if you enable arc, as long as you need to allocate and use objects as usual, the compiler will help you insert retain and release, You don't need to manually add it yourself. ARC retains only objective-c pointer objects, that is, objects that inherit nsobject.
5). Ios 5 and above, with a zero weak reference , because these weak references are set to 0 (that is, nil) after the object is disposed, and then the object is processed as if it were a pointer to a nil value. Before use, declare the method as follows:
1 _weak nsstring *myString; or 2 @property (weak) nsstring *mystring;
Wei iOS Basic Learning Note 12 OC Language Foundation -07 Foundation memory Management