标签:
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。
注:内存管理这一块非常的重要,在笔试面试都会考的到!!!!
标签:
原文地址:http://blog.csdn.net/qq_34798977/article/details/51362175