OC Memory Management Detailed

Source: Internet
Author: User

Objective

Due to the limited memory of the mobile device, we need to manage the memory tightly so as to avoid the resource wasting caused by the memory leak. In OC,只有对象才属于内存管理范围,例如int、struce等基本数据类型不存在内存管理的概念。在iOS开发中,对内存的管理实际上就是对引用计数器的管理。

Three ways of OC memory management
    1. Automatic garbage collection (Automatic garbage Collection);
    2. Manual reference counter (Manual Reference counting) and auto-release pool;
    3. Auto Reference counter (Automatic Reference counting).
Automatic garbage collection

In OC2.0, there is an automatic garbage collection of memory management form, through garbage collection automatically, the system can automatically detect whether the object has other objects, when the program is running, the non-referenced objects will be automatically released.
Description: Automatic garbage collection is not supported in the iOS runtime environment and is supported in OS X environments, but Apple does not recommend this method at this time, instead it is recommended to use ARC instead.

Manual reference Counter (MRC) and auto-release pool; reference counter concept

As the name implies, 一个对象被引用(使用)的次数,每个对象的引用计数器占用4个字节 the reference counter is.
As shown, when you use a to create an object, the RC of object defaults to 1, and when B also points to object, the rc+1=2 of object. Then a pointer does not point to object when the object is rc-1=2-1=1. Finally, when B does not point to object, the object's rc-1=1-1=0, at which point objects are destroyed.
Description:当一个对象被创建的时候,该对象的RC默认为1;当该对象被引用一次,需要调用retain方法,使RC的值+1;当指针失去对该对象的引用,需要调用release方法,使RC的值-1;当RC=0的时候,该对象被系统自动销毁回收。


Paste_image.png Manual Reference Counter (MRC)

MRC is that we control the increase or decrease of the reference counter by artificial means, the impact of the object RC is worth the following methods:

    1. New, Alloc, copy, Mutablecopy, these methods are used to create a new object and take ownership of the object, at which time the value of RC defaults to rc=1;
    2. Retain, the object calls the Retain method, the object's rc+1;
    3. Release, the object calls the release method, the object's RC-1;
    4. The Dealloc,dealloc method does not affect the value of RC, but when RC has a value of 0 o'clock, the system calls the Dealloc method to destroy the object.
      An example is given below:
Declaration and implementation of the 
 //book class @interface book:nsobject@end@implementation the Declaration and implementation of the Book@end//peron class @interface person: nsobject{book *_book;} -(void) Setbook: [book *] book, @end @implementation person-(void) Setbook: (book *) book{if (_book! = book) {//If the newly set book The object is not the book object that was previously pointed to [_book release];//the RC-1 of the previous object _book = [book retain];//current reference rc+1}-(void) Dealloc///Heavy Load Dealloc method destroys the object {[_book release];//because _book controls the book object, _book calls the release method to make RC-1 [super dealloc];//Call the Dealloc method of the parent class,    and must be placed on the last line}} @end//main function test void Main () {book *b=[book new];    Person *p = [person new];    P.book = b; [B release];//b controls the book object, B calls the release method so that RC-1 [P release];//p controls the person object, p calls the release method to make RC-1}  

The

is known by the code above that the set value and value method of the member variable is generated manually, and the reference counter of the member variable in the setter method is also set manually, and we can also generate it from the compiler by @property and the corresponding keyword.
about @property keywords in MRC are as follows:
1. Assign and retain and copy
These keywords are used for memory management of setter methods, If you use assign (which is typically used for non-OC objects), the assignment is performed directly, and if you use retain (typically for OC objects), the new value is retain, the old value is release, and if you use copy, the old value is set to copy the new value. Use assign as default is not displayed.
2. Nonatomic and Atomic
These two keywords are used for multithreading management, nonatomic performance is high, atomic performance is low. Use atomic as default is not displayed. The two keywords
3.readwrite and readonly
are used to indicate whether to generate setter methods, ReadWrite will automatically generate setter and Getter methods, ReadOnly Only the Getter method is generated. Use ReadWrite as default is not displayed.
4. Getter and setter
These two keywords are used to give a different name to the set value and method of the accessor. For example @property (getter=a,setter=b:) int age, which is equivalent to a value method named A, the value method is named B:.
If you use the @property property, the code above can be changed to:

//Book类的声明和实现@interface Book:NSObject@end@implementation Book@end//Peron类的声明和实现@interface Person:NSObject- (void)dealloc;@property(nonatomic,retain) Book *_book;@end@implementation Person- (void)dealloc //重载dealloc方法销毁对象{    [_book release];//用于_book控制了Book对象,_book调用release方法使RC-1    [super dealloc];//调用父类的dealloc方法,而且必须放在最后一行}}@end//主函数测试void main(){    Book *b=[Book new];    Person *p = [Person new];    p.book = b;    [b release];//b控制了Book对象,b调用release方法使RC-1    [p release];//p控制了Person对象,p调用release方法使RC-1}
Circular Reference Memory management principles

for a two Class A containing b,b with a circular reference case , look at the following code:

//Book1类的声明和实现@interface Book1:NSObject@property(nonatomic,retain) Book2 *_book2;- (void)dealloc;@end@implementation Book1- (void)dealloc //重载dealloc方法销毁对象{    [_book2 release];//用于_book控制了Book对象,_book调用release方法使RC-1    [super dealloc];//调用父类的dealloc方法,而且必须放在最后一行}@end//Book2类的声明和实现@interface Book2:NSObject@property(nonatomic,retain) Book1 *_book1;- (void)dealloc;@end@implementation Book2- (void)dealloc //重载dealloc方法销毁对象{    [_book1 release];//用于_book控制了Book对象,_book调用release方法使RC-1    [super dealloc];//调用父类的dealloc方法,而且必须放在最后一行}}@end//主函数测试void main(){    Book1 *b1=[[Book1 alloc] init];    Book2 *b2=[[Book2 alloc] init];    b1.book2 = b2;    b2.book1 = b1;    [b1 release];    [b2 release];}

The following analysis of the main function code, when executing Book1 *b1=[[book1 alloc] init], B1 point to Book1. When you execute BOOK2 *b2=[[book2 alloc] init], B2 points to Book2. When b1.book2 = B2 is executed, the BOOK1 member variable _b2 points to Book2. When B2.book1 = B1 is executed, the BOOK2 member variable _b1 points to Book1. The specific relationship in memory is as shown.

At this point the reference counter of the BOOK1 counter Rc=2,book2 rc=2.
When [B1 release] is executed, B1 releases control over Book1, at which point the Book1 reference counter rc=2-1=1.
When [B2 release] is executed, B2 releases control over Book2, at which point the Book2 reference counter rc=2-1=1.
So since there are still pointers pointing to Book1 and Book2, the relationship between Book1 and Book2 in memory is shown in the black ellipse. So the Dealloc function is not called, so Book1 and Book2 do not destroy the PIN, so that is the result 内存泄露 .


Paste_image.png

For this scenario, you only need to use retain at one end of the @property attribute declaration in Book1 and Book2, and one end using assign. One @property in @property (nonatomic,retain) Book1 *_book1 or Nonatomic,retain (BOOK2) *_book2 Retian will be changed to assign. Specific reasons for their own analysis.

Look at the following circular reference case, only use assign.

@interface Book:NSObject@property(nonatomic,assign)id  instance;  //此处必须用assign- (void)dealloc;@end@implementation Book- (void)dealloc //重载dealloc方法销毁对象{    [_instance release];//用于_book控制了Book对象,_book调用release方法使RC-1    [super dealloc];//调用父类的dealloc方法,而且必须放在最后一行}@endvoid mian(){    Book b1 = [[Book alloc] init];    Book b2 = [[Book alloc] init];    b1.instance = b2;    b2.instance = b1;    [b1 release];    [b2 release];}

You can analyze if @property (nonatomic,assign) ID instance; Changing the assign to retain will also cause a memory leak.

Use of the Autorelease pool

As the name implies, Autorelease automatically releases objects without our manual release. From the above code we know that in the main function, after creating the object obj, always manually invoke the [obj release] method, which undoubtedly makes the workload larger and meaningless to our technical growth. To reduce this meaningless work, you can use the Autorelease pool method.
The Autorelease pool is automatically freed, and the object in the Autorelease pool is created with the Autorelease method invoked, and the final release method of the object within the pool is called by the compiler.

There are two ways to create a autorelease pool:

1.通过@autoreleasepool方法创建,如下:@autoreleasepool{//在大括号内创建的对象最后不需要手动调用release方法。}
2. 通过NSAutoreleasePool类创建,如下:NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]  init];//此范围为自动释放池[pool release];

Examples of use of Autorelease pool are as follows:

void main(){     @autoreleasepool    {        Person p = [[[Person alloc] init] autorelease]; //调用autorelease方法        //不需要再调用[p release];方法,超过autoreleasepool作用域会自动调用该方法。    }    }

In a method that returns an object , it is best to use an auto-free pool to dispose of the object, because if the newly created object is returned as a return value, the object can be deferred by automatically releasing pools, because the object cannot be disposed before it is returned. The sample code is as follows:

-(Person *)getNewPerson{    Person p* = [[[Person alloc] init] autorelease];    //do something    return p;}或者{    Person p* = [[Person alloc] init] ;    //do something    return [p autorelease];}

Note the point:

  1. The release method cannot be called multiple times, which is called at the time of the call, otherwise prone to wild pointer errors.
  2. The Autorelease method is called multiple times when an object is created, which can cause wild pointer errors.
  3. Newly created objects in the auto-free pool are not necessarily added to the release pool, such as objects created by new, alloc, copy, mutablecopy, are not added to the auto-free pool, and the release method must be called manually to release the object. If you want to add newly created objects to the auto-free pool, you must call the Autorelease method.
  4. Using the Autorelease method does not increase the value of the reference counter, it simply means that the object is added to the auto-release pool.
Auto Reference counter (ARC)

ARC will be controlled automatically by the compiler to complete the object reference counter, without the need for manual completion.
In Arc mode, new objects that are created are usually qualified by the following keywords.

    1. __strong (default), a strong pointer decorated by __strong, will not be destroyed as long as a strong pointer is pointed to, whenever a strong pointer points to an object, the object's rc+1;
    2. __weak, the weak pointer is modified by __weak, the object pointed by the weak pointer does not change the RC value, the weak pointer only represents a reference to the object, and when the object pointed to by the weak pointer is destroyed, the value of the weak pointer becomes nil;
    3. __unsafe_unretained, the object pointed to by the __unsafe_unretained-modified object pointer does not change the RC value, it only represents a reference to the object, and when the object is destroyed, the value of the pointer does not become nil. Still retains its original address;

In Arc mode, the retain and release methods in the MRC are not available because ARC does not require us to manage the memory manually, and everything is done by the compiler.
In MRC mode, assigning an object pointer to another object pointer is as follows:

Person p1 = [Person new];Person p2 = [Person new];[p2 release]//在p2失去对对象的控制权时需要先releasep2 = p1;//进行赋值操作

But in arc mode, we can completely not care about how to do it, just need to assign the value directly:

Person p1 = [Person new];Person p2 = [Person new];p2 = p1;//进行赋值操作
Circular references in Arc mode

In Arc mode, the @property property's modifiers for memory management are strong and weak (retain and assign under MRC are not available), indicating whether the declaration is a strong pointer or a weak pointer. It is usually decorated with strong, but not in circular references.

In this case, one end is decorated with strong and one end is decorated with weak. If you use the strong modifier, it will cause the object's loop to persist, causing a memory leak.

//Book1类的声明和实现@interface Book1:NSObject@property(nonatomic,strong) Book2 *_book2;@end@implementation Book1@end//Book2类的声明和实现@interface Book2:NSObject@property(nonatomic,weak) Book1 *_book1;@end@implementation Book2@end//主函数测试void main(){    Book1 *b1=[[Book1 alloc] init];    Book2 *b2=[[Book2 alloc] init];    b1.book2 = b2;    b2.book1 = b1;}

The following is a circular reference, which can only be used with weak. If you use the strong modifier, it causes the object's loop to persist, causing a memory leak.

@interface Book:NSObject@property(nonatomic,weak)id  instance;  //此处必须用assign@end@implementation Book@endvoid mian(){    Book b1 = [[Book alloc] init];    Book b2 = [[Book alloc] init];    b1.instance = b2;    b2.instance = b1;}

Note the point:

  1. Automatic release of the pool can still be used in arc mode;
  2. The retain, release, Retaincount, Autorelease and other methods under MRC are not available.
  3. Note the selection of strong and weak under circular references.
Summarize

The essence of memory management is the manipulation of object reference counters, and understanding memory management operations in MRC mode helps us understand OC memory management. Memory management only for the object, note the MRC and ARC under the @property property keyword selection, in MRC mode, OC Objects usually use the Retain keyword, non-OC objects use the Assign keyword, but circular reference is an exception, usually requires one end to use assign, One end uses retain; in Arc mode, OC objects typically use the strong keyword, and non-OC objects use the Assign keyword, but circular references are an exception, often requiring a single end to use the strong, and a weak at the end.

OC Memory Management Detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.