autoreleasepool 貫穿app的整個周期汛兜。
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
autoreleasepool 是一種機制巴粪,實現(xiàn)了放入其中的對象,可以再生命周期結(jié)束后自動進行釋放粥谬。
AutoreleasePoolPage 以雙向鏈表組合肛根,實現(xiàn)autoreleasepool;
這個 id *next 存放新進來的對象漏策。
void *context = objc_autoreleasePoolPush();
// {}中的代碼
objc_autoreleasePoolPop(context);
當(dāng)調(diào)用objc_autoreleasePoolPush()時派哲,會在棧中加入一個哨兵。調(diào)用對應(yīng)的objc_autoreleasePoolPop掺喻,就會釋放中間加入的所有對象芭届。
runloop相關(guān)
App啟動后,蘋果在主線程 RunLoop 里注冊了兩個 Observer感耙,其回調(diào)都是 _wrapRunLoopWithAutoreleasePoolHandler()褂乍。
第一個 Observer 監(jiān)視的事件是 Entry(即將進入Loop),其回調(diào)內(nèi)會調(diào)用 _objc_autoreleasePoolPush() 創(chuàng)建自動釋放池即硼。其 order 是-2147483647逃片,優(yōu)先級最高,保證創(chuàng)建釋放池發(fā)生在其他所有回調(diào)之前只酥。
第二個 Observer 監(jiān)視了兩個事件: BeforeWaiting(準(zhǔn)備進入休眠) 時調(diào)用_objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush() 釋放舊的池并創(chuàng)建新池褥实;Exit(即將退出Loop) 時調(diào)用 _objc_autoreleasePoolPop() 來釋放自動釋放池呀狼。這個 Observer 的 order 是 2147483647,優(yōu)先級最低性锭,保證其釋放池子發(fā)生在其他所有回調(diào)之后赠潦。
在主線程執(zhí)行的代碼叫胖,通常是寫在諸如事件回調(diào)草冈、Timer回調(diào)內(nèi)的。這些回調(diào)會被 RunLoop 創(chuàng)建好的 AutoreleasePool 環(huán)繞著瓮增,所以不會出現(xiàn)內(nèi)存泄漏怎棱,開發(fā)者也不必顯示創(chuàng)建 Pool 了。
參考
https://blog.sunnyxx.com/2014/10/15/behind-autorelease/
https://draveness.me/autoreleasepool#AutoreleasePoolPage
https://juejin.im/post/5a687e356fb9a01c94060620