
本系列博客是本人的源码阅读笔记,如果有 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
方法被调用了。
当然,如果换成
int main(int argc, const char * argv[]) {
@autoreleasepool {
[NSArray arrayWithObjects:@"1",@"2",nil] ;
}
return 0;
也是会调用NSArray
的autorelease
方法的。
基于以上三个试验,我们可以大概总结出ARC 下对象由 Autoreleasepool 管理的几种情况:
本文完整版详见笔者小专栏:https://xiaozhuanlan.com/topic/5942178603
广告
我的首款个人开发的APP壁纸宝贝上线了,欢迎大家下载。
