天天看點

OC對象之旅 weak弱引用實作分析

OC對象之旅 weak弱引用實作分析

根據調試資訊,發現兩者的差別是:

OC對象之旅 weak弱引用實作分析
OC對象之旅 weak弱引用實作分析
OC對象之旅 weak弱引用實作分析

是以重點就在 storeweak這個方法中,let's do it

storeweak源碼的如下:

OC對象之旅 weak弱引用實作分析

ps:初始化isa那部分為何能阻止死鎖,我沒有看懂 該函數流程如下:

OC對象之旅 weak弱引用實作分析

重點來了:

sidetable

sidetable是一個結構體,定義如下

OC對象之旅 weak弱引用實作分析

taggedpointer

簡單的說,這是一種優化手段,即将對象的值,存入對象的位址中,這些工程師簡直喪心病狂,就為了省一點記憶體嘛!

進入正題,看看怎麼實作弱引用的

先看看注冊的過程吧

先從這行數的參數說起,參數有4個

OC對象之旅 weak弱引用實作分析

後三個參數不用解釋,主要解釋第一個參數,weak_table_t,定義如下

沒錯,weak_table_t就是寄存在sidetable中

OC對象之旅 weak弱引用實作分析

定義中我們重點關注weak_entry_t

weak_entry_t是最終存放對象和引用指針的地方,referent是被引用的對象,聯合體union釋義如下

OC對象之旅 weak弱引用實作分析

注冊引用過程中,重點關注下面代碼:

建立

通過weak_entry_t的源碼,可以看到建立一個weak_entry_t的過程是

OC對象之旅 weak弱引用實作分析

調整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中,同時更新相關計數器。 上面過程的流程如下:

OC對象之旅 weak弱引用實作分析
OC對象之旅 weak弱引用實作分析

消除弱引用

消除弱引用過程同注冊大緻相同,隻是部分地方是相反操作,不做贅述了

上一篇: Eth-Trunk

繼續閱讀