本系列博客是本人的源碼閱讀筆記,如果有 iOS 開發(fā)者在看 runtime 的寝优,歡迎大家多多交流苫亦。為了方便討論尖淘,本人新建了一個微信群(iOS技術討論群),想要加入的著觉,請?zhí)砑颖救宋⑿牛簔hujinhui207407村生,【加我前請備注:ios 】,本人博客http://www.kyson.cn 也在不停的更新中饼丘,歡迎一起討論
本文完整版詳見筆者小專欄:https://xiaozhuanlan.com/runtime
背景
上篇文章講解了arr_init()趁桃,大概了解了AutoReleasePoolPage的數(shù)據(jù)結構。但我相信大家可能還只是一知半解。例如:
- Autoreleasepool 與 Runloop 的關系
- ARC 下什么樣的對象由 Autoreleasepool 管理
- 子線程默認不會開啟 Runloop卫病,那出現(xiàn) Autorelease 對象如何處理油啤?不手動處理會內存泄漏嗎?
本文就帶大家稍微分析一下這三個問題
分析
- Autoreleasepool 與 Runloop 的關系
這個問題先不討論了蟀苛,因為本系列博客討論的是autorelease pool益咬。這里給大家大概說一下:
系統(tǒng)在主線程 RunLoop 里注冊了兩個 Observer,其回調都是 _wrapRunLoopWithAutoreleasePoolHandler()第一個 Observer 監(jiān)視的事件是 Entry(即將進入Loop)帜平,其回調內會調用 _objc_autoreleasePoolPush() 創(chuàng)建自動釋放池幽告。其 order 是-2147483647,優(yōu)先級最高裆甩,保證創(chuàng)建釋放池發(fā)生在其他所有回調之前冗锁。第二個 Observer 監(jiān)視了兩個事件: BeforeWaiting(準備進入休眠) 時調用 _objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush() 釋放舊的池并創(chuàng)建新池;Exit(即將退出Loop) 時調用 _objc_autoreleasePoolPop() 來釋放自動釋放池嗤栓。這個 Observer 的 order 是 2147483647冻河,優(yōu)先級最低,保證其釋放池子發(fā)生在其他所有回調之后茉帅。
- ARC 下什么樣的對象由 Autoreleasepool 管理
要回答這個問題叨叙,我們通過代碼來解釋即可,鍵入如下代碼:
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSObject *obj = [[NSObject alloc] init];
}
return 0;
}
可以發(fā)現(xiàn)什么都沒有發(fā)生堪澎。接下來擂错,我們再輸入如下代碼發(fā)現(xiàn):
int main(int argc, const char * argv[]) {
@autoreleasepool {
__autoreleasing NSObject *obj = [[NSObject alloc] init];
}
return 0;
發(fā)現(xiàn)
可以發(fā)現(xiàn)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
廣告
我的首款個人開發(fā)的APP壁紙寶貝上線了刹悴,歡迎大家下載。