當前位置:成語大全網 - 新華字典 - iOS - weak 底層原理

iOS - weak 底層原理

[toc]

weak

blogs.com/guohai-stronger/p/10161870.html

/p/2b12666b351f

weak 是弱引用, 用weak來修飾、描述所引用對象的計數器並不會加1, 而且weak會在引用對象被釋放的時候自動置為nil, 這也就避免了野指針訪問壞內存而引起崩潰的情況,

weak也可以解決循環引用。

assign 可用來修飾基本數據類型, 也可修飾OC的對象, 但如果用 assign 修飾對象類型指向的是壹個強指針, 當指向的這個指針釋放之後, 它仍指向這塊內存, 必須要手動給置為nil, 否則會產生野指針, 如果還通過此指針操作那塊內存, 會導致 EXC_BAD_ACCESS 錯誤, 調用了已經被釋放的內存空間;

而 weak 只能用來修飾OC對象, 而且相比assign比較安全, 如果指向的對象消失了, 那麽它會自動置為nil, 不會導致野指針。

ARC 是 LLVM + Runtime 互相協作的結果

開啟ARC後, LLVM編譯器會自動幫我們在相應位置生成 release、retain、autorelease

在作用域 (大括號) 結束的位置添加 release

弱引用這種, 是通過runtime處理的

編譯之後的weak, 通過 objc_ownership(weak) 實現 weak 方法, objc_ownership 字面意思是:獲得對象的所有權, 是對對象weak的初始化的壹個操作。

通過 weak 編譯解析, 可以看出 weak 是通過 runtime 初始化並維護的;

weak 和 strong 都是 OC ARC 的修飾詞, 而 strong 是通過 runtime 維護的壹個自動計數表結構。

weak 指針的地址值是所指對象指針的地址

weak 全局表 weak_table_t 中的存儲 weak 定義的對象的表結構 weak_entry_t,

weak_entry_t 是存儲在弱引用表中的壹個內部結構體, 它負責維護和存儲指向壹個對象的 所有弱引用hash表

可以看到 DisguisedPtr<objc_object *> 相當於 objc_object ** ;

即 weak_referrer_t 就是 objc_object ** 的別名

初始化weak變量時, runtime會調用 objc_initWeak 函數, 初始化新的weak指針指向對象的地址;

objc_initWeak 函數內部會調用 objc_storeWeak() 函數, objc_storeWeak() 函數的作用是用來更新指針的指向, 創建弱引用表。

在最後會調用 clearDeallocating 函數。而 clearDeallocating 函數首先根據對象的地址獲取weak指針地址的數組, 然後緊接著遍歷這個數組, 將其中的數組開始置為nil, 把這個 entry從weak 表中刪除, 最後壹步清理對象的記錄。

當 weak 指向的對象被釋放時, 編譯器如何讓 weak 指針置為nil的呢?

將弱引用存到壹個弱引用表(哈希表)中, 對象銷毀時, 就從表中取出當前對象的弱引用並清除

註: 關於 SideTable 、 weak_table_t 、 weak_entry_t 參考 《 isa指針 》