runtime 如何實現(xiàn) weak 屬性

要實現(xiàn) weak 屬性,首先要搞清楚 weak 屬性的特點:

weak 此特質(zhì)表明該屬性定義了一種“非擁有關(guān)系” (nonowning relationship)。為這種屬性設(shè)置新值時,設(shè)置方法既不保留新值,也不釋放舊值。此特質(zhì)同 assign 類似, 然而在屬性所指的對象遭到摧毀時,屬性值也會清空(nil out)。

那么 runtime 如何實現(xiàn) weak 變量的自動置nil?

runtime 對注冊的類, 會進行布局,對于 weak 對象會放入一個 hash 表中。 用 weak 指向的對象內(nèi)存地址作為 key,當(dāng)此對象的引用計數(shù)為0的時候會 dealloc,假如 weak 指向的對象內(nèi)存地址是a,那么就會以a為鍵, 在這個 weak 表中搜索,找到所有以a為鍵的 weak 對象,從而設(shè)置為 nil。

對象的內(nèi)存銷毀時間表,分四個步驟:

  1. 調(diào)用 -release :引用計數(shù)變?yōu)榱?/li>
  • 對象正在被銷毀,生命周期即將結(jié)束.
  • 不能再有新的 __weak 弱引用, 否則將指向 nil.
  • 調(diào)用 [self dealloc]
  1. 子類 調(diào)用 -dealloc
  • 繼承關(guān)系中最底層的子類 在調(diào)用 -dealloc
  • 如果是 MRC 代碼 則會手動釋放實例變量們(iVars)
  • 繼承關(guān)系中每一層的父類 都在調(diào)用 -dealloc
  1. NSObject 調(diào) -dealloc
  • 只做一件事:調(diào)用 Objective-C runtime 中的
  1. object_dispose() 方法
  • 調(diào)用 object_dispose()
  • 為 C++ 的實例變量們(iVars)調(diào)用 destructors
  • 為 ARC 狀態(tài)下的 實例變量們(iVars) 調(diào)用 -release
  • 解除所有使用 runtime Associate方法關(guān)聯(lián)的對象
  • 解除所有 __weak 引用
  • 調(diào)用 free()

驗證:

生成weak屬性的對象, 并指向一個對象,當(dāng)對象銷毀之后,指向該對象的weak屬性的對象也會隨之銷毀。

__weak id weakObj1 = nil;
__weak id weakObj2 = nil;
{   
   id obj = [[NSObject alloc] init]; // 引用計數(shù)會增加,這里不會是weak的    
   weakObj1 = obj;   
   weakObj2 = obj;    
  NSLog(@"obj: %@", obj);    
  NSLog(@"weakObj1: %@", weakObj1);    
  NSLog(@"weakObj2: %@", weakObj2);
}
NSLog(@"weakObj1: %@", weakObj1);
NSLog(@"weakObj2: %@", weakObj2);

輸出為:

obj: <NSObject: 0x60800000bdc0>
weakObj1: <NSObject: 0x60800000bdc0>
weakObj2: <NSObject: 0x60800000bdc0>
weakObj1: (null)
weakObj2: (null)

因為 weak 本身是非擁有的,所有如果是把weakObj1設(shè)置為nil的話,是不會對其他的造成影響的。

參考:<a >吵了個吵 - iOS面試題</a>

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

推薦閱讀更多精彩內(nèi)容