weak指針是如何實(shí)現(xiàn)自動(dòng)設(shè)置為nil的

在ARC中,weak指針修飾的變量會(huì)在指向的對(duì)象銷毀時(shí)自動(dòng)置為nil,系統(tǒng)是怎么做到的呢?這里從本質(zhì)和源碼出發(fā)來(lái)解釋。源碼

iOS系統(tǒng)中維護(hù)著一個(gè)SideTables的哈希表,這個(gè)哈希表用來(lái)管理所有對(duì)象的引用計(jì)數(shù)和weak指針。

一、找到weak指針存儲(chǔ)的位置

SideTables哈希表里面裝著的元素的key為對(duì)象,value為SideTable的結(jié)構(gòu)體!

struct SideTable {
    spinlock_t slock;
    RefcountMap refcnts; // 引用計(jì)數(shù) 
    weak_table_t weak_table; // 弱引用表 
}

由上面可知weak_table_t是系統(tǒng)保存weak指針的結(jié)構(gòu)。

存儲(chǔ)weak指針的結(jié)構(gòu)體weak_table_t

struct weak_table_t {
    weak_entry_t *weak_entries;
    size_t    num_entries;
};

typedef DisguisedPtr<objc_object *> weak_referrer_t;
#define WEAK_INLINE_COUNT 4
struct weak_entry_t {// 本來(lái)是一個(gè)C++結(jié)構(gòu)體, 簡(jiǎn)化后如下
    DisguisedPtr<objc_object> referent;
    weak_referrer_t *referrers;
    weak_referrer_t  inline_referrers[WEAK_INLINE_COUNT]; 
};

由上可知:

  1. referent是存儲(chǔ)被引用對(duì)象的地址.
  2. inline_referrers是用來(lái)裝weak指針的數(shù)組,不過(guò)數(shù)量只有WEAK_INLINE_COUNT=4個(gè).
  3. referrers也是存儲(chǔ)weak指針的數(shù)組,但是當(dāng)inline_referrers不夠的時(shí)候才會(huì)使用的.
二、系統(tǒng)在對(duì)象銷毀時(shí)的做法

在對(duì)象銷毀時(shí)會(huì)做的事情,根據(jù)源碼追蹤重要的步驟:

  1. 調(diào)用dealloc
  2. _objc_rootDealloc(self);
  3. obj->rootDealloc();
  4. object_dispose(this);
  5. 先調(diào)用objc_destructInstance(obj);清楚對(duì)象相關(guān)聯(lián)的東西, 之后再調(diào)用free(obj);釋放對(duì)象。
  6. objc_destructInstance(obj);會(huì)做的事情
// This order is important.
 if (cxx) object_cxxDestruct(obj); 
 if (assoc) _object_remove_assocations(obj);// 清除屬性關(guān)聯(lián)
 obj->clearDeallocating();
  1. clearDeallocating函數(shù)里面會(huì)調(diào)用clearDeallocating_slow();
  2. clearDeallocating_slow();里面會(huì)調(diào)用weak_clear_no_lock(&table.weak_table, (id)this);
  3. weak_clear_no_lock函數(shù)中將referrers數(shù)組或者inline_referrers數(shù)組遍歷,賦值為nil。
最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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