目录
正文
1:NSAutorelease实现原理
1:从 main 函数开始
int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSLog(@"Hello, World!"); } return 0; }
2:@autoreleasepool
2.1:@autoreleasepool
到底是什么?我们在命令行中使用 clang -rewrite-objc main.m
让编译器重新改写这个文件:
$ clang -rewrite-objc main.m
int main(int argc, const char * argv[]) { /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; NSLog((NSString *)&__NSConstantStringImpl__var_folders_49_sdbnp0nd07q4m_sh4_gw52r40000gn_T_main_9e48ee_mi_0); } return 0; }
在这个文件中,有一个非常奇怪的 __AtAutoreleasePool
的结构体,前面的注释写到 /* @autoreleasepopl */
。也就是说 @autoreleasepool {}
被转换为:__AtAutoreleasePool的结构体。
2.2: 通过对比可以发现,苹果通过声明一个__AtAutoreleasePool类型的局部变量 @autoreleasepool被转转换成__AtAutoreleasePool 结构体类型
struct __AtAutoreleasePool { __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();} ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);} void * atautoreleasepoolobj; };
可以看到:
__AtAutoreleasePool() 构造函数调用objc_autoreleasePoolPush(),
~__AtAutoreleasePool() 析构函数调用 objc_autoreleasePoolPop()
2.3:这表明,我们的 main
函数其实是这样的:
int main(int argc, const char * argv[]) { { void * atautoreleasepoolobj = objc_autoreleasePoolPush(); // do whatever you want objc_autoreleasePoolPop(atautoreleasepoolobj); } return 0; }
@autoreleasepool
只是帮助我们少写了这两行代码而已,让代码看起来更美观,然后要根据上述两个方法来分析自动释放池的实现