首页 > 开发 > iOS > 正文

autorelease的对象到底会在什么时候被回收?

2017-09-08 14:04:05  来源:网友分享

我有一个比较大的图片对象,临时的,是在一个循环里,要多次初始化的,用了autorelease,但是循环结束以后,在循环外还是可以看到最后一次的那个对象没被释放。我怀疑其他的对象也没被释放。。。但是我希望在循环以外,这些就被释放啊。。。
autorelease到底会在什么时候释放呢?

解决方案

iOS的运行时是由一个一个runloop组成的,每个runloop都会执行下图的一些步骤:

可以看到,每个runloop中都创建一个Autorelease Pool,并在runloop的末尾进行释放,
所以,一般情况下,每个接受autorelease消息的对象,都会在下个runloop开始前被释放。也就是说,在一段同步的代码中执行过程中,生成的对象接受autorelease消息后,一般是不会在代码段执行完成前释放的。

当然也有让autorelease提前生效的办法:自己创建Pool并进行释放

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];NSArray * array = [[[NSArray alloc] init] autorelease];[pool drain];

上面的array就会在[pool drain]执行时被释放。

所以对于你遇到的问题,可以在for循环外嵌套一个Autorelease Pool进行管理,例如

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];for (int i = 0; i < 10000; i++){    // ... }[pool drain];

但由于你提到了生成的每个实例可能会比较大。只在循环外嵌套,可能导致在pool释放前,内存里已经有10000个实例存在,造成瞬间占用内存过大的情况。

因此,如果你的每个实例仅需要在单次循环过程中用到,那么可以考虑可以在循环内创建pool并释放

for (int i = 0; i < 10000; i++){    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    // ...    [pool drain];}

如果还有疑问,可以参考下面几篇资料:
How does the NSAutoreleasePool Work
http://stackoverflow.com/questions/65...

NSAutoreleasePool Class Reference
https://developer.apple.com/library/m...

Autorelease is fast:
http://www.mikeash.com/pyblog/autorel...