內(nèi)存布局
- 棧(stack):方法調(diào)用箩张,局部變量,是連續(xù)的窗市,高地址向低地址擴(kuò)展
- 堆(heap):通過alloc等分配的對(duì)象先慷,是離散的,低地址向高地址擴(kuò)展咨察,需要手動(dòng)管理
- 未初始化數(shù)據(jù)(bss):未初始化的全局變量等
- 已初始化數(shù)據(jù)(data):已初始化的全局變量等
- 代碼段(text):程序代碼
問題一 :Autoreleasepool是實(shí)現(xiàn)機(jī)制是什么论熙?它是什么時(shí)候釋放內(nèi)部的對(duì)象的?它內(nèi)部的數(shù)據(jù)結(jié)構(gòu)是什么樣的摄狱?當(dāng)我提到哨兵對(duì)象時(shí)脓诡,會(huì)繼續(xù)問哨兵對(duì)象的作用是什么无午,為什么要設(shè)計(jì)它?
編譯器會(huì)將 @autoreleasepool {} 改寫為:
void * ctx = objc_autoreleasePoolPush;
{}
objc_autoreleasePoolPop(ctx);
- objc_autoreleasePoolPush:
把當(dāng)前next位置置為nil祝谚,即哨兵對(duì)象,然后next指針指向下一個(gè)可入棧位置宪迟,AutoreleasePool的多層嵌套,即每次objc_autoreleasePoolPush踊跟,實(shí)際上是不斷地向棧中插入哨兵對(duì)象踩验。 - objc_autoreleasePoolPop:
根據(jù)傳入的哨兵對(duì)象找到對(duì)應(yīng)位置。
給上次push操作之后添加的對(duì)象依次發(fā)送release消息商玫』叮回退next指針到正確的位置。
Autoreleasepool的原理是一個(gè)雙向列表拳昌,它會(huì)對(duì)加入其中的對(duì)象實(shí)現(xiàn)延遲釋放袭异。
當(dāng)Autoreleasepool調(diào)用drain方法時(shí)會(huì)釋放內(nèi)部標(biāo)記為autorelease的對(duì)象
Autoreleasepool數(shù)據(jù)結(jié)構(gòu)
class AutoreleasePoolPage {
magic_t const magic;
id *next;
pthread_t const thread;
AutoreleasePoolPage * const parent;
AutoreleasePoolPage *child;
uint32_t const depth;
uint32_t hiwat;
};
哨兵對(duì)象類似一個(gè)指針,指向自動(dòng)釋放池的棧頂位置炬藤,它的作用就是用于標(biāo)記當(dāng)前自動(dòng)釋放池需要釋放內(nèi)部對(duì)象時(shí)御铃,釋放到那個(gè)地方結(jié)束,每次入棧時(shí)它用于確定添加的位置沈矿,然后再次移動(dòng)到棧頂上真。
Autoreleasepool詳細(xì)內(nèi)容 容易理解
問題二 :哪些對(duì)象會(huì)放入到Autoreleasepool中?
有兩種情況生成的對(duì)象會(huì)加入到autoreleasepool中:
- 非alloc/new/copy/mutablecopy 開始的方式初始化時(shí)
- id的指針或?qū)ο蟮闹羔樤跊]有顯示指定時(shí)