一、什么时候是用@autoreleasepool
1、写基于命令行的的程序时,就是没有UI框架,如AppKit、Cocoa
框架时。
2、当我们的应用有需要创建大量的临时变量的时候,可以是用@autoreleasepool
来减少内存峰值。
3、for循环大量的图片数据等内存消耗大的场景。
二、AutoreleasePool的实现原理
在编译时@autoreleasepool{}
被转换为一个__AtAutoreleasePool
,通常这个结构体会在初始化时调用objc_autoreleasePoolPush()
方法,在析构时调用objc_autoreleasePoolPop()
方法。而这些方法都是对AutoreleasePoolPage
的简单封装。AutoreleasePool
并没有单独的结构,而是由若干个AutoreleasePoolPage
以双向链表的形式组合而成(分别对应结构中的parent
指针和child
指针)。所以想深入理解AutoreleasePool
必须首先了解AutoreleasePoolPage
。
可以使用clang -rewrite-objc
命令将Objective-C
代码重写成C++
代码。
clang -rewrite-objc main.m
extern "C" __declspec(dllimport) void * objc_autoreleasePoolPush(void);
extern "C" __declspec(dllimport) void objc_autoreleasePoolPop(void *);
struct __AtAutoreleasePool {
__AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}
~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}
void * atautoreleasepoolobj;
};
#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)
int main(int argc, char * argv[]) {
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
}
}
从上述重写代码表现可以看出,单个autoreleasepool
的运行过程可以简单地理解为objc_autoreleasePoolPush()
、[obj release]
和objc_autoreleasePoolPop(void *)
三个过程。
网友评论