iOS开发之深入理解runtimeRuntime源码iOS

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

2019-02-28  本文已影响27人  kyson老师

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

runtime logo

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

背景

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

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

分析

这个问题先不讨论了,因为本系列博客讨论的是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,优先级最低,保证其释放池子发生在其他所有回调之后。

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

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

上一篇 下一篇

猜你喜欢

热点阅读