iOS runtime探究(五): 從runtime開始深入weak實現機理

你要知道的runtime都在這里

轉載請注明出處 http://www.lxweimin.com/p/4a32fb8648a3

本文主要講解runtime相關知識,從原理到實踐,由于包含內容過多分為以下五篇文章詳細講解,可自行選擇需要了解的方向:

本文是系列文章的第五篇文章,也是系列文章的最后一篇從runtime開始: 深入weak實現機理,本文主要講解runtime是如何實現weak修飾符的。
weak修飾符我們一點也不陌生在開發中經常用到,最主要的作用是為了防止引用循環(retained cycle),經常用于blockdelegate,在前面幾篇文章中已經講解了weak的基本使用和引用循環,如果有興趣可以參考文章iOS @property探究(一): 基礎詳解iOS @property探究(二): 深入理解iOS block探究(一): 基礎詳解iOS block探究(二): 深入理解,相關方法和特點本文不再贅述了。

weak

weak不論是用作property修飾符還是用來修飾一個變量的聲明其作用是一樣的,就是不增加新對象的引用計數,被釋放時也不會減少新對象的引用計數,同時在新對象被銷毀時,weak修飾的屬性或變量均會被設置為nil,這樣可以防止野指針錯誤,本文要講解的也正是這個特性,runtime如何將weak修飾的變量的對象在銷毀時自動置為nil

那么runtime是如何實現在weak修飾的變量的對象在被銷毀時自動置為nil的呢?一個普遍的解釋是:runtime對注冊的類會進行布局,對于weak修飾的對象會放入一個hash表中。用weak指向的對象內存地址作為key,當此對象的引用計數為0的時候會dealloc,假如weak指向的對象內存地址是a,那么就會以a為鍵在這個weak表中搜索,找到所有以a為鍵的weak對象,從而設置為nil

了解了以上知識后就可以深入runtiem代碼來看看具體實現細節,有興趣的讀者可以繼續閱讀。

深入runtime理解weak

這部分內容參考《Objective-C高級編程:iOS與OS X多線程和內存管理》,可以看出具體的實現方式就是使用了一個HashTable

NSString *name = [[NSString alloc] initWithString: @"Jiaming Chen"];
__weak NSString *weakStr = name;

當為weakStr這一weak類型的對象賦值時,編譯器會根據name的地址為key去查找weak哈希表,該表項的值為一個數組,將weakStr對象的地址加入到數組中,當name變量超出變量作用域或引用計數為0時,會執行dealloc函數,在執行該函數時,編譯器會以name變量的地址去查找weak哈希表的值,并將數組里所有 weak對象全部賦值為nil。

備注

由于作者水平有限,難免出現紕漏,如有問題還請不吝賜教。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容