63 (OC)* NSAutoreleasePool 自动释放池

目录

正文

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 只是帮助我们少写了这两行代码而已,让代码看起来更美观,然后要根据上述两个方法来分析自动释放池的实现

总结

猜你喜欢

转载自www.cnblogs.com/zyzmlc/p/12008991.html
63