__weak簡析

當一個 __weak 類型的指針指向的對象被釋放時,該指針會自動被置成nil,因此__weak關鍵字修飾的指針又被稱為智能指針。那么這個功能是如何實現的呢?

id __weak obj1 = obj; 

會轉化為

id obj1;  
objc_initWeak(&obj1, obj);  
objc_destoryWeak(&obj1);  

即編譯器會通過objc_initWeak函數初始化__weak修飾的變量,當變量的作用域結束后會通過objc_destoryWeak函數釋放該變量。objc_initWeak函數實際干的活是:

objc1 = 0;  
objc_storeWeak(&obj1, obj);  

這里是先將指針objc1置成0,再調用objc_storeWeak函數使得obj1指向obj對象。
接下來的objc_destoryWeak函數的實際操作如下:

objc_storeWeak(&obj1, 0); 

也就是說,讓obj1指針指向的內容變成空。

__weak實現原理

實際上,objc_storeWeak函數會把第二個參數的對象的地址作為key,并將第一個參數(__weak關鍵字修飾的指針的地址)作為值,注冊到weak表中。如果第二個參數為0(說明對應的對象被釋放了),則將weak表中將整個key-value鍵值對刪除,這就是__weak關鍵字的核心思想!

weak表和引用計數表類似,都是通過hash表實現的。如果使用weak表,將被釋放的對象地址作為key去檢索,就能很高效的獲取對應的指向該對象的類型為__weak的指針變量的地址。同時很容易理解,一個對象可能有多個__weak指針指向,因此一個對象地址key可能對應多個值。

在調用對象的release方法時,會在其中一步調用objc_clear_deallocating函數,該函數會執行以下操作:以當前對象的地址作為key,從weak表中獲取對應的值----指向該對象的__weak類型的指針變量;將取到的所有指針變量的值賦值為nil;從weak表中刪除該key對應的整條記錄。

如果大量使用附有__weak修飾符的變量會消耗響應的CPU資源,因此,應該盡量少使用__weak修飾符。

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

推薦閱讀更多精彩內容

  • 1.ios高性能編程 (1).內層 最小的內層平均值和峰值(2).耗電量 高效的算法和數據結構(3).初始化時...
    歐辰_OSR閱讀 29,645評論 8 265
  • Swift1> Swift和OC的區別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,145評論 1 32
  • 在拉薩 文/閆殿才 《一》 在拉薩,你可以像鷹一樣地看 世界很清澈。藍天,白云,經幡 拉薩河蜿蜒。像膜拜者 轉山,...
    閆殿才閱讀 651評論 30 59
  • 導語:隨著大數據的發展,現在出現的列式存儲和列式數據庫,如Hbase。它與傳統的行式數據庫有很大區別的。 定義 行...
    jackLee閱讀 15,255評論 1 9
  • 我愛你時,你是一切;我不愛你,翻了那頁。越是在錯誤的過去中糾纏,就離前方的幸福越遠。 -01- 芋頭終于忍無可忍,...
    小馬不怕過河閱讀 1,587評論 6 19