autorelease
当一个对象调用autorelease时,会将这个对象放到位于栈定的释放池中。是一种支持引用计数器的内存管理方式,在执行[对象名 autorelease]时会将对象放到位于栈顶的释放池,等到结束时,对每个对象发送release消息。注意,这里只是发送release消息,如果引用计数器依然不为0,则改对象不会释放。
自动释放池的创建:
autoreleasepool{//自动释放池的开始
.....
}//自动释放池的结束
autorelease的基本用法
(1)会将对象放到一个自动释放池中
(2)当自动释放池被销毁时,会对池子里的所有对象做一次release
(3)会返回对象本身
(4)调用完autorelease方法后,对象的计数器不受影响(销毁时影响)
在autorelease的模式下,下述方法是合理的,即可以正确返回结果,也不会造成内存泄露
ClassA *Func1()
{
ClassA *obj = [[[ClassAalloc]init]autorelease];//对象调用autorelease方法,将对象加到自动释放池中
return obj;
}
autorelease 注意及错误用法
1)并不是放到自动释放池中,都会自动加入到自动释放池
int main(int argc, const char *argv[]) {
@autoreleasepool {
person *p =[Person new];
[p release];//正常释放,因为没有加入到自动释放池
}
2)在自动释放池的外部发送autorelease 不会被加入到自动释放池中
int main(int argc, const char *argv[]) {
@autoreleasepool {
}
person *p = [Person new];
[pautorelease]//因为是对象在自动释放池外部调用autorelease,该对象病没有加入到自动释放池中
return0;
}
3)不管这个对象是在自动释放池内还是外创建的,只要在自动释放池内写一个[p1autorelease];p1就会被放到自动释放池中。注意autorelease是一个方法,且只有在自动释放池中使用才有效。
如:
int main(int argc, const char *argv[]) {
person *p =[Person new];//对象在自动释放池外部定义的
@autoreleasepool {
[p autorelease]// 对象在自动释放池中调用的autorelease,该对象加到了自动内存池中
}
return 0;
}
4)自动释放池的嵌套使用
int main(int argc, const char *argv[]) {
Person *p = [Person new];//在自动释放池外部创建的对象
[p retain];
@autoreleasepool {
@autoreleasepool {
[pautorelease];//此时,将p加入到自动释放池中
}
[p autorelease];//在此将p加到另一个自动释放池中
}
return0;
}
5)自动释放池中不适宜放占用内存比较大的对象
尽量避免对大内存使用该方法,对于这种延迟释放机制,还是尽量少用不要把大量循环操作放到同一个 @autoreleasepool 之间,这样会造成内存峰值的上升
autorelease错误用法
(1)连续调用多次autorelease
(2)Alloc之后调用了autorelease,之后又调用了release。
如:
int main(int argc, const char *argv[]) {
Person *p = [Person new];//在自动释放池外部创建的对象
@autoreleasepool {
[p autorelease];//在此将p加到另一个自动释放池中
}//自动释放池结束后会p回释放,
[p release ]//此处的p是僵尸对象,在使用会出错
return0;
}