iOS开发之runtime(22):autorelease浅析

logo

本系列博客是本人的源码阅读笔记,如果有 iOS 开发者在看 runtime 的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:ios 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

本文完整版详见笔者小专栏:https://xiaozhuanlan.com/runtime

背景

上篇文章讲解了arr_init(),大概了解了AutoReleasePoolPage的数据结构。但我相信大家可能还只是一知半解。例如:

  • Autoreleasepool 与 Runloop 的关系
  • ARC 下什么样的对象由 Autoreleasepool 管理
  • 子线程默认不会开启 Runloop,那出现 Autorelease 对象如何处理?不手动处理会内存泄漏吗?

本文就带大家稍微分析一下这三个问题

分析

  • Autoreleasepool 与 Runloop 的关系

这个问题先不讨论了,因为本系列博客讨论的是autorelease pool。这里给大家大概说一下:

系统在主线程 RunLoop 里注册了两个 Observer,其回调都是 _wrapRunLoopWithAutoreleasePoolHandler()第一个 Observer 监视的事件是 Entry(即将进入Loop),其回调内会调用 _objc_autoreleasePoolPush() 创建自动释放池。其 order 是-2147483647,优先级最高,保证创建释放池发生在其他所有回调之前。第二个 Observer 监视了两个事件: BeforeWaiting(准备进入休眠) 时调用 _objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush() 释放旧的池并创建新池;Exit(即将退出Loop) 时调用 _objc_autoreleasePoolPop() 来释放自动释放池。这个 Observer 的 order 是 2147483647,优先级最低,保证其释放池子发生在其他所有回调之后。

  • ARC 下什么样的对象由 Autoreleasepool 管理

要回答这个问题,我们通过代码来解释即可,键入如下代码:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
       NSObject *obj = [[NSObject alloc] init];
    }
    return 0;
}

可以发现什么都没有发生。接下来,我们再输入如下代码发现:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
       __autoreleasing NSObject *obj = [[NSObject alloc] init];
    }
    return 0;

发现


autorelease方法被调用

可以发现autorelease方法被调用了。

当然,如果换成

int main(int argc, const char * argv[]) {
    @autoreleasepool {
       [NSArray arrayWithObjects:@"1",@"2",nil] ;
    }
    return 0;

也是会调用NSArrayautorelease方法的。
基于以上三个试验,我们可以大概总结出ARC 下对象由 Autoreleasepool 管理的几种情况:

本文完整版详见笔者小专栏:https://xiaozhuanlan.com/topic/5942178603

广告

我的首款个人开发的APP壁纸宝贝上线了,欢迎大家下载。

壁纸宝贝

你可能感兴趣的:(iOS开发之runtime(22):autorelease浅析)