iOS weak關(guān)鍵字

????????作為一個面試經(jīng)常被問到的問題,iOS weak關(guān)鍵字

基本概念

????????在iOS中,weak的常用來處理NSTimer,delegate,block的循環(huán)引用問題。它是一個弱引用,在對象釋放之后,weak指針自動指向nil,避免野指針,避免錯誤的內(nèi)存訪問。

如何在對象釋放的時候指針置為nil

? ? ? ? 還記得,第一次,接觸到這個問題,只知道weak是弱引用,對象釋放以后,指針會自動賦值為nil。但是為什么在對象釋放后,指針就成了nil,中間進行了什么樣的操作。

? ? ? ? weak說的簡單一些,其實就相當于一個哈希表,在runtime中,是一個覺weak表的東西。將所指對象的地址作為key,vaule是所有指針地址的一個數(shù)組,因為一個對象,可以有多個weak指針指向它。

? ? ? ? 在對象釋放的時候,會調(diào)用一個函數(shù),我們可以看到關(guān)鍵的一些代碼

for(size_t?i?=?0;?i?<?count;?++i)?{

????????objc_object?**referrer?=?referrers[i];

????????if(referrer)?{

????????????if(*referrer?==?referent)?{

????????????????*referrer?=?nil;

????????????}

????????????elseif(*referrer)?{

????????????????_objc_inform("__weak?variable?at?%p?holds?%p?instead?of?%p.?"

?????????????????????????????"This?is?probably?incorrect?use?of?"

?????????????????????????????"objc_storeWeak()?and?objc_loadWeak().?"

?????????????????????????????"Break?on?objc_weak_error?to?debug.\n",

?????????????????????????????referrer,?(void*)*referrer,?(void*)referent);

????????????????objc_weak_error();

????????????}

????????}

????}

????weak_entry_remove(weak_table,?entry);

這里只截取了少量的代碼,可以看到,在對象釋放的時候,會通過key找到weak表中的vaule,從這個數(shù)組中,依次把指針設(shè)為nil,最后,把weak表相關(guān)的記錄也全部刪除。

weak 表實現(xiàn)原理

weak 的實現(xiàn)原理可以概括一下三步:

1、初始化時:runtime會調(diào)用objc_initWeak函數(shù),初始化一個新的weak指針指向?qū)ο蟮牡刂贰?/p>

2、添加引用時:objc_initWeak函數(shù)會調(diào)用 objc_storeWeak() 函數(shù), objc_storeWeak() 的作用是更新指針指向,創(chuàng)建對應(yīng)的弱引用表。

3、釋放時,調(diào)用clearDeallocating函數(shù)。clearDeallocating函數(shù)首先根據(jù)對象地址獲取所有weak指針地址的數(shù)組,然后遍歷這個數(shù)組把其中的數(shù)據(jù)設(shè)為nil,最后把這個entry從weak表中刪除,最后清理對象的記錄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容