1. AutoreleasePool介绍
Autorelease pool blocks provide a mechanism whereby you can relinquish ownership of an object, but avoid the possibility of it being deallocated immediately (such as when you return an object from a method). Typically, you don’t need to create your own autorelease pool blocks, but there are some situations in which either you must or it is beneficial to do so
AutoreleasePool提供了一种延长对象生命周期和避免立即销毁的机制,比如函数Return对象时。通常你不用自己建立AutoreleasePool,但在某些场景下你必须自己创建或是能从使用AutoreleasePool中受益。
我们简单的用代码说明下为什么需要AutoreleasePool,下面我们来模拟下[NSArray array]的实现
+ (instancetype)array {
NSArray *array = [[NSArray alloc] init];
return array; //[array autorelease]编译器自动插入autorelease操作
}
array作为局部变量不是应该在出函数作用域时就销毁了吗?但是为什么我们依旧能得到初始化后的对象?这里就是编译默认为我们插入了autorelease操作,使array加入最顶层的AutoreleasePool从而避免了变量在出作用域后立马释放的尴尬情况。
上述文档提到我们通常不需自己创建AutoreleasePool①;但在some situations我们又不得不创建②;如果在特定场景下使用AutoreleasePool我们还能从中受益,这里的benefit又指的是什么呢③
下述给出官方文档的解释:
The AppKit and UIKit frameworks process each event-loop iteration (such as a mouse down event or a tap) within an autorelease pool block. Therefore you typically do not have to create an autorelease pool block yourself, or even see the code that is used to create one
① AppKit与UIKit在每次Runloop迭代时会默认在autorelease pool下执行
If you are writing a program that is not based on a UI framework, such as a command-line tool.
② 如果你是基于非UI framework的命令行编程,你必须自己创建autorelease pool,否则可能造成autoreleased对象的内存泄漏
If you spawn a secondary thread.You must create your own autorelease pool block as soon as the thread begins executing; otherwise, your application will leak objects. (See Autorelease Pool Blocks and Threads for details.)
② 如果你自己创建了子线程,你必须创建autorelease pool,否则可能造成autoreleased对象的内存泄漏
If you write a loop that creates many temporary objects.You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application.
③ 如果你在循环中创建了大量的临时对象(autoreleased对象),你应该在每次循环迭代间使用autorelease pool,这样能在下次循环前对对象进行销毁从而有效地降低系统内存使用峰值
官方文档: Using Autorelease Pool Blocks
官方文档: NSAutoreleasePool |