Objective-C RunTime 学习笔记 之 AutoReleasPool
1、結構
struct magic_t {/* 魔法 */static const uint32_t M0 = 0xA1A1A1A1; # ? define M1 "AUTORELEASE!"static const size_t M1_len = 12;uint32_t m[4];/* 省略各種方法 */ # ? undef M1 };/* AutotRelease 重要:重載了new和delete運算符號,使每個Page對象固定大小 */ class AutoreleasePoolPage? { #define POOL_SENTINEL nilstatic pthread_key_t const key = AUTORELEASE_POOL_KEY; /* TSD __PTK_FRAMEWORK_OBJC_KEY3 */static uint8_t const SCRIBBLE = 0xA3;? // 0xA3A3A3A3 after releasingstatic size_t const SIZE =? #if PROTECT_AUTORELEASEPOOLPAGE_MAX_SIZE;? // must be multiple of vm page size #elsePAGE_MAX_SIZE;? // size and alignment, power of 2 (CGS. 4096 < bytes per 80386 page >) #endifstatic size_t const COUNT = SIZE / sizeof(id);magic_t const magic;id *next; ? /* objc 對象列表指向下一個未使用的區域 */pthread_t const thread; /* page對應線程 *//* 鏈表結構 */AutoreleasePoolPage * const parent; /* 父 */AutoreleasePoolPage *child; ? ? ? ? /* 子 */uint32_t const depth; ? ? ? ? ? ? ? /* 鏈表深度 */uint32_t hiwat;// SIZE-sizeof(*this) bytes of contents follow//省略各種方法//00000哨兵分割線//各種objc對象, }2、 每個線程對應一個AutoReleasePoolPage 的對象列表
2.1) 線程銷毀的時候,釋放AutoReleasePoolPage 以及所有對象
2.2) AutoReleasePoolPage 為C++對象,由于重載了new 和 delete 運算符,確保每一個Page分配固定大小(貌似4K)。在類的實例變量/方法列表后存儲Foundation對象。而類的next 成員變量則指向下一個Foundation對象。AutoReleasePoolPage 有判斷是否為空和滿的成員函數,以此來判斷當前線程是否新創建一個AutoReleasePool對象。沒創建一個對象,都會設置parent、chilid屬性,構成雙向鏈表,而hotPage則是存儲在線程的本地存儲中。系統初始化時會給線程初始化鉤子函數??int r __unused = pthread_key_init_np(AutoreleasePoolPage::key,? AutoreleasePoolPage::tls_dealloc); 確保在線程銷毀的時候,釋放AutoReleasePool, 由于hotPage存存在TLS中,并且page為雙向鏈表,可以通過hotPage遍歷整個Page倆表,確保釋放Page對象。
? ? ? 每個oc對象發送 autorelease 消息或者使用__autorelease 修飾的時候,從當前線程取出hotPage(), 整個函數從線程本地存儲中取,如果沒有AutoReleasePoolPage鏈表則創建一個,否則取出AutoReleasePoolPage,查看是否full,如果full則創建一個新的AutoReleasePoolPage,設置parent 和 child屬性, 然后設置為hotPage(存入線程中本地存儲中 TLS)。
@autoreleasepool {
//some code
}
所有使用 @autoreleasepool block起來的代碼,都會在形成
void *pool = AutoReleasePoolPage::push();
//some code
AutoReleasePoolPage::pop(pool);
3、 主線程AutoReleasePoolPage何時pop?
文檔中說每個 event loop(鼠標事件、點擊事件等)都會在事件的will 時 pool->push(),did時 pool->pop(void *).。OS 會在主線程的RunLoop循環注冊一些列觀察者,在進入時調用 void *pool = AutoReleasePoolPage::push(); ,退出時調用 AutoReleasePoolPage::pop(pool); 這樣子確保每一次循環都進行pool的釋放。
轉載于:https://www.cnblogs.com/chengsh/p/8630628.html
總結
以上是生活随笔為你收集整理的Objective-C RunTime 学习笔记 之 AutoReleasPool的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Codeforeces 954C Mat
- 下一篇: 操作系统(五)CPU调度