__weak修飾符

下面著重探討2個問題的內部實現原理

1.若附有__weak修飾符的變量所引起的對象被廢棄,則將nil賦值給該變量
2.使用__weak修飾的變量,即是使用注冊到autoleasepool中的對象

<pre>id __weak obj1 = obj; //假設變量obj附加__strong修飾符且對象被賦值</pre>

<pre>id obj1; objc_initweak(&obj1,obj); objc_destroyWeek (&obj1);</pre>
通過objc_initWeak函數初始化附有__waek修飾符的變量,在變量作用域結束時通過objc_destoryWeak函數釋放該變量.
如下源碼所示,objc_initWeak函數講附有__waek修飾符的變量初始化為0后,會將賦值的對象作為參數滴啊用objc_storeWeak函數.
<pre>obj1= 0; objc_storeWeak (&obj1, obj); //objc_destroyWeek函數將0作為參數調用objc_storeWeak函數. objc_storeWeak(&obj1, 0);</pre>

objc_storeWeak函數把第二參數的賦值對象的地址未做鍵值,將第一參數的附有__weak修飾符的變量的地址注冊到weak表中.如果第二參數為0,則把變量的地址從weak表中刪除.

weak表

weak表與引用計數表相同,作為[散列表](a href = "http://www.cnblogs.com/dolphin0520/archive/2012/09/28/2700000.html")被實現.如果使用weak表,將廢棄對象的地址作為鍵值進行檢索,就能搞死的獲取對象的附有__weak修飾符的變量地址,另由于一個對象可同時賦值給多個附有__weak修飾符的變量中,所以對于一個鍵值,可以注冊多個變量的地址.

釋放對象時,廢棄誰都不持有的對象的同時,程序的動作是怎樣的呢? 下面我們來跟蹤觀察.對象將通過objc_release函數釋放.
(1)objc_release
(2)因為引用計數為0所以執行delloc
(3)_objc_rootDealloc
(4)objc_dispose
(5)objc_destructInstance
(6)objc_clear_deallocating

對象被廢棄時最后調用的objc_clear_deallocating函數的動作如下:

1.從weak表中獲取廢棄對象的地址為鍵值的記錄.
2.將包含在記錄中的所有附有__weak修飾符變量的地址,賦值為nil.
3.從weak表中刪除該記錄.
4.從引用計數標中刪除廢棄對象的地址為鍵值的記錄

根據上述步驟,前面說的吐過有__weak修飾符的變量引用的對象被廢棄,則將nil賦值給該變量這一操作,則會消耗相應的CPU資源.最好是只在需要避免循環引用時用__weak修飾符.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容