iOS Weak指標原理

2021-10-07 21:42:59 字數 2116 閱讀 9563

-

(void

)viewdidload

nslog

(@"2222 %@"

,strong_animal)

;//2222

nslog

(@"2222 %@"

,weak_animal)

;//2222 (null)

nslog

(@"2222 %@"

,unsafe_animal)

;//crash

}

如果用__unsafe_unretained,當物件釋放後,在訪問指標會crash。

如果用__weak,當物件釋放後,再訪問weak_animal指標為nil

我們來看看物件釋放時發生了什麼?

還會發現

void objc_object::

sidetable_cleardeallocating()

table.refcnts.

erase

(it);}

table.

unlock()

;}||

void

weak_clear_no_lock

(weak_table_t *weak_table, id referent_id)

weak_referrer_t *referrers;

size_t count;

if(entry-

>

out_of_line()

)else

for(size_t i =

0; i < count;

++i)

elseif(

*referrer)}}

weak_entry_remove

(weak_table, entry)

;}

裡面有幾個結構: sidetables,sidetable ,weak_table

1:sidetables

是乙個64個元素長度的hash陣列,裡面儲存了sidetable。sidetables的hash鍵值就是乙個物件obj的位址。sidetabls可以通過全域性的靜態函式獲取:sidetable& table = sidetables()[this];

static stripedmap

&sidetables()

2:sidetable

主要存放了oc物件的引用計數和弱引用相關資訊

struct sidetable 

~sidetable()

//省略其他資訊....

};

refcountmaprefcnts

以disguisedptr為key的hash表,用來儲存oc物件的引用計數(僅在未開啟isa優化 或 在isa優化情況下isa_t的引用計數溢位時才會用到)。

weak_table_tweak_table

儲存物件弱引用指標的hash表。是oc weak功能實現的核心資料結構。

struct weak_table_t 

;

weak_entry_t *weak_entries;
這是乙個hash陣列。通過物件的位址,算出hash值,對應到具體的桶,每個桶裡面放的是乙個weak指標的陣列。清除的時候就是遍歷裡面的的weak指標,全部置為nil;

void

weak_clear_no_lock

(weak_table_t *weak_table, id referent_id)

// .....}}

}

總結構大致如下

iOS weak的底層實現

weak底層千千萬,吾竟裝作看不見.weak基本用法 weak是弱引用,用weak描述修飾或者所引用物件的計數器不會加一,並且會在引用的物件被釋放的時候自動被設定為nil,大大避免了野指標訪問壞記憶體引起崩潰的情況,另外weak還可以用於解決迴圈引用。weak原理概括 weak表其實是乙個hash ...

iOS weak 記憶體釋放問題

我們都知道weak 關鍵字可以解決記憶體不釋放問題,但是使用上有些講究。看 import uikit var str hello,playground class name class person let person person person.test 執行之後,控制台並沒有輸出name de...

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...