runtime源码剖析—— 自动释放池

  • autoreleasepool 的功能、特性,用法都在之前内存管理的文章中说过了,这篇博客主要站在源码的角度来分析一下 autoreleasepool 到底是什么。

autoreleasepool究竟是什么

新建一个iOS项目,用clang重写一下main.m(在命令行中使用 clang -rewrite-objc main.m 让编译器重新改写这个文件)。在main.cpp文件的最后,看到main函数变成了这样:

// 原本iOS项目的main.m
int main(int argc, char * argv[]) {
   
    @autoreleasepool {
   
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

//clang重新改写以后的main.m
int main(int argc, char * argv[]) {
   
    /* @autoreleasepool */ {
    __AtAutoreleasePool __autoreleasepool; 
        return UIApplicationMain(argc, argv, __null, NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class"))));
    }
}

也就是说 @autoreleasepool {} 被转换为一个 __AtAutoreleasePool 结构体:

{
   
    __AtAutoreleasePool __autoreleasepool;
}

为了弄清这行代码的意义,我们搜索一下__AtAutoreleasePool,它的定义是这样的:

struct __AtAutoreleasePool {
   
  __AtAutoreleasePool() {
   atautoreleasepoolobj = objc_autoreleasePoolPush();}
  ~__AtAutoreleasePool() {
   objc_autoreleasePoolPop(atautoreleasepoolobj);}
  void * atautoreleasepoolobj;
};

这个结构体会在初始化时调用 objc_autoreleasePoolPush() 方法,会在析构时调用 objc_autoreleasePoolPop 方法。

这表明,我们的 main 函数在实际工作时其实是这样的:

int main(int argc, const char * argv[]) {
   
    {
   
        void * atautoreleasepoolobj = objc_autoreleasePoolPush();
        
        // do whatever you want
        
        objc_autoreleasePoolPop(atautoreleasepoolobj)<
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值