一、对象------>release(retain -1)----------->(当retain count=0时)dealloc方法调用-------->销毁
说明:
1、销毁对象时肯定先走release方法,如果之后retain count还大于1,则不会释放如果retain count=0,则自动执行dealloc方法,进行销毁
2、执行alloc 方法和copy方法,retain count才会加1.
3、指针赋值时,retain count 不会+1,要想+1,手动调用retain
二、当创建一个对象时,有四种方式 alloc,new,copy, mutablecopy,
用完了以后需要手动调用release才行。那么有没有不需要手 动调用的。答案:autorelease
在创建对象的时候这样做
[[[classA alloc] init] autorelease] 这样建立的对象,就具备autorelase能力, 后面就不需要再调用release了。那为什么?
iphone项目启动后,xcode会帮你建立自动释放池auto release pool ,这个自动释放池中会建立一个数组,存放那些具备autorelease能力的对象。
只有当程序退出时或手动调用pool release时,自动释放池会释放其中所有autorlease能力的对象,让retain count全部减1,如果此时还大于1则不会调用alloc释放对象。
注意事项;
1、autorelease不便大量使用,因为容易造成内存不足。
2、[NSString stringwithFormat:@"123"]这样创建的对象是具备autorelease能力的,所以自动释放池释放的时候,会让retain count-1,然后看一下是不是等于0,决定是否调用alloc方法看是否可以回收。
如果你想让他当全局变量,不想让其回收的话,那么你可以手动调用一下retain,然后最终,你自己决定再release
练习 :
for (int i = 0 ; i < largeNumber; i++) {
NSString *str = [NSString stringWithFormat:@"hello -%04d",i];
}
这个题,str对象能否释放。
分析:
以上是一个消息循环, 所以此时会自动创建一个runloop释放池,然后具备autorelease能力的str对象是存到这里的。只有当循环结束的时候,释放池才会释放所有autolease对象。
所以无法做到循环一次就释放一次。如果让每一次的循环结束时都释放一次内存,怎么做呢?
答案是:创建局部自动释放池。
for (int i = 0 ; i < largeNumber; i++) {
@autoreleasepool {
NSString *str = [[NSString alloc]initWithFormat:@"hello -%04d",i];
}
}
总结:做多线程开发时,需要在线程调度方法中手动添加自动释放池,尤其是当执行循环的时候,如果循环内部有使用类的快速创建方法创建的对象, 一定要将循环体放到自动释放池中。