
根據調試資訊,發現兩者的差別是:
是以重點就在 storeweak這個方法中,let's do it
storeweak源碼的如下:
ps:初始化isa那部分為何能阻止死鎖,我沒有看懂 該函數流程如下:
重點來了:
sidetable
sidetable是一個結構體,定義如下
taggedpointer
簡單的說,這是一種優化手段,即将對象的值,存入對象的位址中,這些工程師簡直喪心病狂,就為了省一點記憶體嘛!
進入正題,看看怎麼實作弱引用的
先看看注冊的過程吧
先從這行數的參數說起,參數有4個
後三個參數不用解釋,主要解釋第一個參數,weak_table_t,定義如下
沒錯,weak_table_t就是寄存在sidetable中
定義中我們重點關注weak_entry_t
weak_entry_t是最終存放對象和引用指針的地方,referent是被引用的對象,聯合體union釋義如下
注冊引用過程中,重點關注下面代碼:
建立
通過weak_entry_t的源碼,可以看到建立一個weak_entry_t的過程是
調整weak_table_t的容量大小
當實際的數目大于old_size(old_size就是mask的大小+1),就去調整大小,同時重置max_hash_displacement為0,通過calloc函數,動态配置設定mask個的記憶體,然後通過循環,将原有的weak_entry_t插入到新的容器中,在插入的過程中,更新max_hash_displacement.
在weak_table_t插入weak_entry_t
過程比較簡單,也是利用hash處理,友善後面查找。
在weak_table_t查找對象是通過循環周遊的方式,過程如下
在已有的weak_entry_t中加入引用
該過程同在weak_table_t中插入weak_entry_t如出一轍,要注意的是需要判斷引用的個數,當引用個數大于weak_inline_count時,需要将原有的引用指針也移到referrers中,同時更新相關計數器。 上面過程的流程如下:
消除弱引用
消除弱引用過程同注冊大緻相同,隻是部分地方是相反操作,不做贅述了