代码
在MRC环境下
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pool release];
在ARC or MRC 环境下均可使用
@autoreleasepool {
}
内存管理
Cocoa
的内存管理主要依赖于Reference Counting
, 而NSAutoReleasePool
就是用来支持它的。
Autorelease pool
中存放的对象会在其自身干枯(drain)时被release
。
对象的销毁
我们都知道当一个object
的release
方法被触发时, 这个对象就被销毁了, 再也不能对它有任何引用, 否则就会出现异常。
但如果在销毁它时触发的是autorelease
方法, 那这个object
就进入了对应的autorelease pool
, 它的生命就被延长了(当pool drain
时才真正被销毁).
在引用计数的环境中,Cocoa期望有一个可以随时可用的自动释放池。如果一个池不可用,则自动释放的对象不会被释放,您会泄漏内存。在这种情况下,您的程序通常会记录适当的警告消息。
应用程序包在事件循环的每一个循环开始时在主线程上创建一个自动释放池,并在结束时将其耗尽,从而释放在处理事件时生成的任何自动释放的对象。如果您使用的是应用程序包,那么您通常不需要创建自己的池。如果您的应用程序在事件循环中创建了许多临时的自动回调对象,那么创建“本地”自动回调池将有助于最小化峰值内存占用。
创建autorelease pool
NSAutoReleasePool
的初始化与普通的NSObject
一样, 都是alloc+init
, 不过pool
不能被retain
, 因为在drain
的时候默认就销毁它自身了.
还有一点需要注意的是, 通常在销毁pool
的时候用的不是它的release
方法, 而是drain
!
原因是为了让程序同时兼容Reference Counting
内存管理环境 与 Garbge Collection
环境, 因为在Garbage Colloection
环境中drain
的作用是触发collect garbage
动作.
一般来说在应用的main thread
中, 已经存在了一个autorelease pool
. 有两种情况需要开发者自己新建autorelease pool
:
1、在main thread
中, 在某个方法中出现大量的autoreleased objects
, 为了避免memory footprint
的增大, 可以手动创建一些autorelease pool
用来drain objects
.
2、创建新的thread
, 并在其中访问了Cocoa
, 需要在访问的前创建autorelease pool
, 访问结束后drain
.
最后一点, 在每个thread
中都会维持一个stack
(栈堆), 其中放置着所有在这个thread
中创建但未销毁的pool
, 每当一个新的pool
创建后, 它就位于stack
的最顶端, 相应autoreleased object
就会放入其中. 当pool drain
的时候, 它就会从stack
的顶端移除, 并且release掉其包含的
objects`.
AutoreleasePoolPage
在MRC环境下,我们可以看到-[NSAutoreleasePool release]
方法最终是通过调用 <