1、 autorelease的基本使用
(1) 给某个对象发送一条 autorelease 消息时,就会将这个对象加到一个自动释放池中。
(2) 当自动释放池销毁时,会给池子里面的所有对象发送一条 release 消息。
(3) 调用autorelease方法时并不会改变对象的计数器,并且会返回对象本身。
(4) autorelease实际上只是把对 release 的调用延迟了,对于每一次autorelease,系统只是把该对象放入了当前的 autorelease pool中,当该 pool 被释放时,该 pool 中的所有对象会被调用release。
2、 自动释放池的创建
(1) ios 5.0后
(2)ios 5.0前
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// .....
[pool release]; // 或[pool drain];
(3)在程序运行过程中,可以创建多个自动释放池,它们是以栈的形式存在内存中。
(4)OC对象只需要发送一条 autorelease 消息,就会把这个对象添加到最近的自动释放池中(栈顶的释放池)。
3、应用实例
(1)跟release的对比
1> 以前:
Book *book = [[Book alloc] init];
[book release];
2>现在:
Book *book = [[[Book alloc] init] autorelease];
// 不要再调用[book release];
- 一般可以为类添加一个快速创建对象的类方法
+ (id)book
{
return [[[Book alloc] init] autorelease];
}
外界调用[Book book]时,根本不用考虑在什么时候释放返回的Book对象
4、规律
(1)一般来说,除了alloc、new或copy之外的方法创建的对象都被声明了autorelease
(2)比如下面的对象都已经是autorelease的,不需要再release
NSNumber *n = [NSNumber numberWithInt:100];
NSString *s = [NSString stringWithFormat:@"jack"];
NSString *s2 = @"rose";
5、autorelease的好处
(1)不用再关心对象释放的时间
(2)不用再关心什么时候调用release
6、autorelease的使用注意:
(1)占用内存较大的对象不要随便使用autorelease
(2)占用内存较小的对象使用autorelease,没有太大影响。
7、错误用法
(1)在alloc之后使用autorelease,再使用release就会出现野指针错误。
@autoreleasepool
{
Person *p =[ [[Person alloc] init] autorelease]
{
[p release];
}
}
(2)连续多次使用autorelease,出现野指针错误。
@autoreleasepool
{
Person *p =[[ [[Person alloc] init] autorelease] autorelease];
}