Category 的實(shí)現(xiàn)原理
Category 實(shí)際上是Category_t的結(jié)構(gòu)體,在運(yùn)行時(shí)痛倚,新添加的方法规婆,都被以倒序插入到原有方法列表的最前面,所以不同的Category,添加同一個(gè)方法蝉稳,執(zhí)行的實(shí)際上是最后一個(gè)抒蚜。
Category 在剛剛編譯完的時(shí)候,和原來(lái)的類是分開的耘戚,只有在程序運(yùn)行起來(lái)后嗡髓,通過(guò)Runtime,Category 和原來(lái)的類收津,才會(huì)合并到一起饿这。
isa 指針的理解
isa 等價(jià)于 is kind of
實(shí)例對(duì)象的isa指向類對(duì)象
類對(duì)象指向元類對(duì)象
元類對(duì)象的isa指向元類的基類
isa 有兩種類型
純指針,指向內(nèi)存地址
NON_POINTER_ISA撞秋,除了內(nèi)存地址长捧,還存有其他信息。
runtime 如何實(shí)現(xiàn)weak屬性吻贿?
weak 此特征表明該屬性定義了一種【非擁有關(guān)系】唆姐。為這中屬性設(shè)置新值時(shí),設(shè)置方法既不持有新值,也不釋放舊值奉芦。
runtime 對(duì)注冊(cè)的類赵抢,會(huì)進(jìn)行內(nèi)存布局,從一個(gè)粗粒度的概念上來(lái)講声功,這時(shí)候會(huì)有一個(gè)hash表烦却,這是一個(gè)全局表,表中是用weak指向的對(duì)象內(nèi)存地址作為key先巴,用所有指向該對(duì)象的weak指針表作為value其爵。當(dāng)此對(duì)象的引用計(jì)數(shù)為0的時(shí)候會(huì)delloc,假如該對(duì)象內(nèi)存地址是a,那么就會(huì)以a為key伸蚯,在這個(gè)weak表中搜索摩渺,找到所有以a為鍵的weak對(duì)象,從而設(shè)置為nil剂邮。
runtime 如何實(shí)現(xiàn)weak屬性具體流程大致分為3步:
1摇幻、初始化時(shí),runtime會(huì)調(diào)用objc_initWeak函數(shù)挥萌,初始化一個(gè)新的weak指針,指向?qū)ο蟮刂贰?br>
2引瀑、添加引用時(shí):objc_initWeak函數(shù)會(huì)調(diào)用objc_storeWeak()函數(shù)帜矾,objc_storeWeak()的作用是更新指針指向(指針可能原來(lái)指向其他對(duì)象屡萤,這時(shí)候需要將該weak指針與舊對(duì)象接觸綁定,會(huì)調(diào)用到weak_unregister_no_lock)如果指針指向的新對(duì)象非空翔曲,則創(chuàng)建對(duì)應(yīng)的弱引用表,將weak指針與新對(duì)象進(jìn)行綁定掠械,會(huì)調(diào)用到weak_register_no_lock。在這個(gè)過(guò)程中,為了防止多線程中競(jìng)爭(zhēng)沖突,會(huì)有一些鎖的操作层扶。
3镜会、釋放時(shí):調(diào)用clearDeallocating函數(shù),clearDeallocating函數(shù)首先根據(jù)對(duì)象地址獲取所有weak指針地址的數(shù)組扒袖,然后遍歷這個(gè)數(shù)組把其中的數(shù)據(jù)設(shè)為nil野瘦,最后把這個(gè)entry從weak表中刪除吏廉,最后清理對(duì)象的記錄席覆。