iOS weak的底層實現

2021-08-18 23:01:06 字數 2911 閱讀 7819

weak底層千千萬,吾竟裝作看不見...

weak基本用法

weak是弱引用,用weak描述修飾或者所引用物件的計數器不會加一,並且會在引用的物件被釋放的時候自動被設定為nil,大大避免了野指標訪問壞記憶體引起崩潰的情況,另外weak還可以用於解決迴圈引用。

weak原理概括

weak表其實是乙個hash(雜湊)表,key是所指物件的位址,value是weak指標的位址陣列。weak的底層實現的原理是什麼?

runtime維護了乙個weak表,用於儲存指向某個物件的所有weak指標。weak表其實是乙個hash表,key是所指物件的位址,value是weak指標的位址(這個位址的值是所指物件指標的位址)陣列。

為什麼value是陣列?因為乙個物件可能被多個弱引用指標指向

weak原理實現步驟

weak 的實現原理可概括三步:

1、初始化時:runtime會呼叫objc_initweak函式,初始化乙個新的weak指標指向物件的位址。

初始化流程圖

2、新增引用時:objc_initweak函式會呼叫 objc_storeweak() 函式, objc_storeweak() 的作用是更新指標指向,建立對應的弱引用表。

更新指標,建立弱引用表

3、釋放時,呼叫cleardeallocating函式。cleardeallocating函式首先根據物件位址獲取所有weak指標位址的陣列,然後遍歷這個陣列把其中的資料設為nil,最後把這個entry從weak表中刪除,最後清理物件的記錄。

weak實現三步驟詳細過程:1、初始化時:runtime會呼叫objc_initweak函式,objc_initweak函式會初始化乙個新的weak指標指向物件的位址。

示例**:

nsobject *obj = [[nsobject alloc] init];

id __weak obj1 = obj;

當我們初始化乙個weak變數時,runtime會呼叫 nsobject.mm 中的objc_initweak函式。

這個函式在clang中的宣告如下:

id objc_initweak(id *object, id value);

而對於 objc_initweak() 方法的實現如下:

id objc_initweak(id *location, id newobj) 

// 這裡傳遞了三個 bool 數值

// 使用 template 進行常量引數傳遞是為了優化效能

return storeweakfalse/*old*/, true/*new*/, true/*crash*/>

(location, (objc_object*)newobj);

}

這裡先判斷了其指標指向的類物件是否有效,無效直接釋放返回,不再往深層呼叫函式。否則,object將通過bjc_storeweak函式被註冊為乙個指向value的__weak物件。

注意:objc_initweak函式有乙個前提條件:就是object必須是乙個沒有被註冊為__weak物件的有效指標。而value則可以是null,或者指向乙個有效的物件。

2、新增引用時:objc_initweak函式會呼叫 objc_storeweak() 函式, objc_storeweak() 的作用是更新指標指向,建立對應的弱引用表。

objc_storeweak的函式宣告如下:

id objc_storeweak(id *location, id value);

objc_storeweak() 的具體實現,請參考weak弱引用實現的方式,這裡的實現很複雜,沒看懂,沒看懂。

3、釋放時,呼叫cleardeallocating函式。cleardeallocating函式首先根據物件位址獲取所有weak指標位址的陣列,然後遍歷這個陣列把其中的資料設為nil,最後把這個entry從weak表中刪除,最後清理物件的記錄。

當weak引用指向的物件被釋放時,又是如何去處理weak指標的呢?當釋放物件時,其基本流程如下:

1、呼叫objc_release

2、因為物件的引用計數為0,所以執行dealloc

3、在dealloc中,呼叫了_objc_rootdealloc函式

4、在_objc_rootdealloc中,呼叫了object_dispose函式

5、呼叫objc_destructinstance

6、最後呼叫objc_clear_deallocating,詳細過程如下:

a. 從weak表中獲取廢棄物件的位址為鍵值的記錄

c. 將weak表中該記錄刪除

d. 從引用計數表中刪除廢棄物件的位址為鍵值的記錄

拓展補充weak,__unsafe_unretained, unowned 與 assign區別致謝參考部落格:

weak 弱引用的實現方式

ios 底層解析weak的實現原理(包含weak物件的初始化,引用,釋放的分析)

iOS weak 自動置為nil的實現

runtime 維護了乙個weak表,weak table t 用於儲存指向某乙個物件的所有weak指標。weak表其實是乙個雜湊表,key是所指物件的位址,value是weak指標的位址的陣列。在物件 的時候,就會在weak表中進行搜尋,找到所有以這個物件位址為鍵值的weak物件,從而置位nil。...

iOS weak學習碰到的疑問

weak弱引用並不持有物件,所以賦值給 weak修飾符的變數也不會改變計數器的值.main.m id strongobj3 nil id weak obj1 nil id weak obj1 obj 編譯器的模擬 例如以下 id obj1 objc iniitweak obj1,obj objc d...

tableView的底層實現

通過在cellforrow方法和heightforrow方法列印函式,發現 1.系統首先把所有的cell的位置都計算好,儲存 2.當cell要顯示的時候,就會拿到這個cell去設定frame cell.frame self.frame row 所以萬能的設定cell分割線的方法 1.取消系統的分割線...