内存管理(16.5.10)

来源:互联网 发布:机器人软件开发平台 编辑:程序博客网 时间:2024/06/05 05:36

Cocoa中的内存管理机制:

每一个对象都有一个引用计数(retain count);

对象被创建的时候,引用计数的值是1;

当引用计数值是0的时候,系统会调用自己的dealloc方法将对象销毁;

retainCount 用来打印当前的引用计数/


内存管理原则:

内存管理就是最终的引用计数要平衡,如果最后引用计数大于0则会内存泄漏,如果引用计数等于0还对该对象进行操作,则会出现内存访问失败,程序闪退,所以应设置为nil。

IOS对象都继承于NSObject,改对象有一个retainCount来显示内存的引用计数。


对象操作:

retain、alloc、new 使用后对象的引用计数都+1;

copy :复制一个新的对象(新的内存地址),新对象的引用计数为1,原对象的引用计数不变。

release:释放一个对象后引用计数-1,如果引用计数为0则立刻释放内存,销毁对象。

autorelease:自动释放一个对象后引用计数-1,如果为0不立刻释放,而是交给系统在手机内存不足时释放。


引用计数举例:

// alloc retain release

    Book *aBook = [[Bookalloc]init];// alloc

    NSLog(@"1.retainCount=%d", (int)[aBookretainCount]);//count:1

    

    [aBook retain]; // retain

    NSLog(@"2.retainCount=%d", (int)[aBookretainCount]);//count:2

    

    [aBook retain]; // retain

    NSLog(@"3.retainCount=%d", (int)[aBookretainCount]);//count:3

    

    [aBook release]; // release

    NSLog(@"4.retainCount=%d", (int)[aBookretainCount]);//count:2

    

    [aBook release]; // release

    NSLog(@"5.retainCount=%d", (int)[aBookretainCount]);//count:1

    

    [aBook release];// release count:0 dealloc it

    NSLog(@"6.retainCount=%d", (int)[aBookretainCount]);//count:1这是因为系统延时释放对象所致

    // 这里aBook已经释放了,再次调用release就会报错

    [aBook release];// error:pointer being freed was not allocated



 // alloc copy retain release

    Book *aBook = [[Book alloc] init]; // alloc

    NSLog(@"1.aBook retainCount=%d", (int)[aBook retainCount]);//count:1

    Book *aBook2 = [aBook copy]; // 需要实现Book里的-(id)copyWithZone:(NSZone*)zone方法

    NSLog(@"2.aBook retainCount=%d -- aBook2 retainCount=%d", (int)[aBook retainCount], (int)[aBook2 retainCount]); //count:1 1

    

    [aBook retain]; // retain

    [aBook2 retain]; // retain

    NSLog(@"3.aBook retainCount=%d -- aBook2 retainCount=%d", (int)[aBook retainCount], (int)[aBook2 retainCount]); //count:2 2

    

    [aBook release]; // release

    [aBook2 release]; // release

    NSLog(@"4.aBook retainCount=%d -- aBook2 retainCount=%d", (int)[aBook retainCount], (int)[aBook2 retainCount]); //count:1 1

    

    [aBook retain]; // retain

    [aBook2 retain]; // retain

    NSLog(@"5.aBook retainCount=%d -- aBook2 retainCount=%d", (int)[aBook retainCount], (int)[aBook2 retainCount]); //count:2 2

    

    [aBook release]; // release

    [aBook2 release]; // release

    NSLog(@"6.aBook retainCount=%d -- aBook2 retainCount=%d", (int)[aBook retainCount], (int)[aBook2 retainCount]); //count:1 1

    

    [aBook release]; // release

    [aBook2 release]; // release

    NSLog(@"7.aBook retainCount=%d -- aBook2 retainCount=%d", (int)[aBook retainCount], (int)[aBook2 retainCount]); //count:0 0

    

    // 再次调用 release就报错

    [aBook release]; // error:pointer being freed was not allocated

    [aBook2 release]; // error:pointer being freed was not allocated


 // new release

    Book *aBook = [Book new]; // 等效于 [[Book alloc] init]

    NSLog(@"1.aBook retainCount=%d", (int)[aBook retainCount]);//count:1

    

    [aBook release];

    NSLog(@"2.aBook retainCount=%d", (int)[aBook retainCount]);//count:0

    

    //再调用就报错了

    [aBook release]; // error:pointer being freed was not allocated


调用到的方法:

引用计数为0的时候调用系统的方法:

- (void)dealloc

{

    self.name =nil;//优先使用!

//    [_name release];

//    _name = nil;

    [super dealloc];

}


copy复制时调用:

- (id)copyWithZone:(NSZone*)zone

{

    return [BookallocWithZone:zone];//从新生成一块新内存

}


内存管理总结:

谁创建,谁释放。如果你通过alloc、new或copy来创建一个对象,那么你必须调用release或autorelease。

retain一个对象,就要调用调用release或autorelease,retain与release保持一致。

Release一个对象后,立即把指针晴空。[obj release] obj = nil;

指针赋值给另一个指针记得retain。ClassA *obj2 = obj1; [obj2 retain];

在一个函数中创建并返回对象,需要把这个对象设置成autorelease,而不能设置为release。

在研究retain count的时候,我不建议用NSString。因为在下面的语句中,

NSString *str1 = @”constant string”;str1的retain count是个很大的数字。Objective-C对常

量字符串做了特殊处理。当然,如果你这样创建NSString,得到的retain count

依然为1
NSString *str2 = [NSString

stringWithFormat:@”123”]; 



 

除了alloc、new、retain或copy之外的方法创建的对象都自动被声明了autorelease,不用再去释放。

从Xcode6.0开始,系统默认使用 ARC机制(即自动释放内存机制),之前的都是 MRC(手动释放内存机制)

在Targets - Bubild Settings ,输出objc 。 可以让工程使用ARC或MRC。



注:内存管理这一块非常的重要,在笔试面试都会考的到!!!!



1 0
原创粉丝点击