iOS的內(nèi)存管理

一、引用計(jì)數(shù)值存儲(chǔ)位置

OC對(duì)象的引用計(jì)數(shù)值存儲(chǔ)在對(duì)象的isa指針中,isa的結(jié)構(gòu)如下:

isa結(jié)構(gòu)體:
union isa_t
{
    struct  {
        ...
        uintprt_t has_sidetable_rc;  // 引用計(jì)數(shù)是否存在sidetable中
        uintprt_t extra_rc ; // 存儲(chǔ)的值為引用計(jì)數(shù)值-1
    }
}

如果has_sidetable_rc==0,引用計(jì)數(shù)值就存儲(chǔ)在extra_rc中;如果has_sidetable_rc ==1,表示計(jì)數(shù)值超出了extra_rc 的存儲(chǔ)范圍(19個(gè)字節(jié)),此時(shí)計(jì)數(shù)值存儲(chǔ)在sidetable中。

sideTable結(jié)構(gòu):
struct SideTable {
        spinlock_t slock;
        RefcountMap refcnts;
        weak_table_t weak_table;
}

sideTable的refcnts存儲(chǔ)著引用計(jì)數(shù),refcnts是個(gè)散列表,存儲(chǔ)數(shù)據(jù)是以對(duì)象地址為key,引用計(jì)數(shù)值為value存儲(chǔ)。sideTable是靜態(tài)數(shù)據(jù),獲取某個(gè)對(duì)象引用計(jì)數(shù)值時(shí),通過(guò)對(duì)象地址,在靜態(tài)的sideTable表中進(jìn)行查找。

二、如何做到自動(dòng)釋放的

    1. 工程的main入口有一個(gè)autoReleasePool,每個(gè)線程內(nèi)部也自帶了autoReleasePool。主線程的runloop循環(huán)時(shí)會(huì)創(chuàng)建一個(gè)autoreleasePool,結(jié)束時(shí)會(huì)會(huì)觸發(fā)pool里的內(nèi)存釋放邏輯,處理完成后銷毀該autoreleasePool,下個(gè)循環(huán)開(kāi)始時(shí)會(huì)創(chuàng)建新的pool。子線程不會(huì)一直創(chuàng)建、銷毀pool。
    1. arc下的對(duì)象初始化后,編譯器會(huì)自動(dòng)往后面追加autorelease標(biāo)識(shí),程序運(yùn)行時(shí)就會(huì)把這個(gè)對(duì)象存儲(chǔ)在最近的autoReleasePool中。autoReleasePool要傾倒時(shí),會(huì)檢測(cè)里面的對(duì)象是否有引用計(jì)數(shù)為0的,有則觸發(fā)改對(duì)象的dealloc邏輯

三、Dealloc

引用計(jì)數(shù)為0時(shí),會(huì)觸發(fā)dealloc方法,dealloc過(guò)程是先子類->父類...->NSObject。
dealloc做的工作包括:

1. C++函數(shù)釋放: objc_cxxDestruct
2. 移除關(guān)聯(lián)屬性:_object_remove_assocations
3. 將弱引用自動(dòng)設(shè)置nil: weak_clear_no_lock(&table.weak_table,(id)this)
4. 引用計(jì)數(shù)處理:table.refcnts.erase(this)
5. 銷毀對(duì)象:free(obj)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容