你要知道的runtime都在這里
轉(zhuǎn)載請注明出處 http://www.reibang.com/p/4a32fb8648a3
本文主要講解runtime
相關(guān)知識(shí),從原理到實(shí)踐蹄葱,由于包含內(nèi)容過多分為以下五篇文章詳細(xì)講解,可自行選擇需要了解的方向:
- 從runtime開始: 理解面向?qū)ο蟮念惖矫嫦蜻^程的結(jié)構(gòu)體
- 從runtime開始: 深入理解OC消息轉(zhuǎn)發(fā)機(jī)制
- 從runtime開始: 理解OC的屬性property
- 從runtime開始: 實(shí)踐Category添加屬性與黑魔法method swizzling
- 從runtime開始: 深入weak實(shí)現(xiàn)機(jī)理
本文是系列文章的第五篇文章府怯,也是系列文章的最后一篇從runtime開始: 深入weak實(shí)現(xiàn)機(jī)理紊撕,本文主要講解runtime
是如何實(shí)現(xiàn)weak
修飾符的驻襟。
weak
修飾符我們一點(diǎn)也不陌生在開發(fā)中經(jīng)常用到,最主要的作用是為了防止引用循環(huán)(retained cycle)
黄痪,經(jīng)常用于block
和delegate
,在前面幾篇文章中已經(jīng)講解了weak
的基本使用和引用循環(huán)盔然,如果有興趣可以參考文章iOS @property探究(一): 基礎(chǔ)詳解桅打、iOS @property探究(二): 深入理解、iOS block探究(一): 基礎(chǔ)詳解愈案、iOS block探究(二): 深入理解挺尾,相關(guān)方法和特點(diǎn)本文不再贅述了。
weak
weak
不論是用作property
修飾符還是用來修飾一個(gè)變量的聲明其作用是一樣的站绪,就是不增加新對象的引用計(jì)數(shù)遭铺,被釋放時(shí)也不會(huì)減少新對象的引用計(jì)數(shù),同時(shí)在新對象被銷毀時(shí)恢准,weak
修飾的屬性或變量均會(huì)被設(shè)置為nil
魂挂,這樣可以防止野指針錯(cuò)誤,本文要講解的也正是這個(gè)特性顷歌,runtime
如何將weak
修飾的變量的對象在銷毀時(shí)自動(dòng)置為nil
锰蓬。
那么runtime
是如何實(shí)現(xiàn)在weak
修飾的變量的對象在被銷毀時(shí)自動(dòng)置為nil
的呢?一個(gè)普遍的解釋是:runtime
對注冊的類會(huì)進(jìn)行布局眯漩,對于weak
修飾的對象會(huì)放入一個(gè)hash表
中芹扭。用weak
指向的對象內(nèi)存地址作為key
,當(dāng)此對象的引用計(jì)數(shù)為0的時(shí)候會(huì)dealloc
赦抖,假如weak
指向的對象內(nèi)存地址是a
舱卡,那么就會(huì)以a
為鍵在這個(gè)weak表
中搜索,找到所有以a
為鍵的weak
對象队萤,從而設(shè)置為nil
轮锥。
了解了以上知識(shí)后就可以深入runtiem
代碼來看看具體實(shí)現(xiàn)細(xì)節(jié),有興趣的讀者可以繼續(xù)閱讀要尔。
深入runtime理解weak
這部分內(nèi)容參考《Objective-C高級(jí)編程:iOS與OS X多線程和內(nèi)存管理》舍杜,可以看出具體的實(shí)現(xiàn)方式就是使用了一個(gè)HashTable
。
NSString *name = [[NSString alloc] initWithString: @"Jiaming Chen"];
__weak NSString *weakStr = name;
當(dāng)為weakStr
這一weak
類型的對象賦值時(shí)赵辕,編譯器會(huì)根據(jù)name
的地址為key去查找weak哈希表
既绩,該表項(xiàng)的值為一個(gè)數(shù)組,將weakStr
對象的地址加入到數(shù)組中还惠,當(dāng)name
變量超出變量作用域或引用計(jì)數(shù)為0時(shí)饲握,會(huì)執(zhí)行dealloc
函數(shù),在執(zhí)行該函數(shù)時(shí),編譯器會(huì)以name
變量的地址去查找weak哈希表
的值救欧,并將數(shù)組里所有 weak
對象全部賦值為nil衰粹。
備注
由于作者水平有限,難免出現(xiàn)紕漏笆怠,如有問題還請不吝賜教铝耻。