Runtime系列導(dǎo)讀
介紹
OC是一門動(dòng)態(tài)性比較強(qiáng)的編程語(yǔ)言,允許很多操作推遲到程序運(yùn)行時(shí)再進(jìn)行。
OC的動(dòng)態(tài)性就是由Runtime來(lái)支撐和實(shí)現(xiàn)的,Runtime是一套C語(yǔ)言的API,封裝了很多動(dòng)態(tài)性相關(guān)的函數(shù)平時(shí)編寫的OC代碼,底層都轉(zhuǎn)換成Runtime API(主要是objc_msgSend和objc_msgSendSuper)進(jìn)行調(diào)用。
我們可以利用Runtime做以下具體場(chǎng)景應(yīng)用:
- 關(guān)聯(lián)對(duì)象(AssociatedObject)給分類添加屬性;
- 遍歷類的所有成員變量;
- 交換方法實(shí)現(xiàn);
- 利用消息轉(zhuǎn)發(fā)機(jī)制解決方法找不到的異常問(wèn)題
方法存儲(chǔ)
實(shí)例對(duì)象與類的關(guān)系
定義
科普下實(shí)例對(duì)象(instance)、類(class)、元類(meta-class)。
- 類在面向?qū)ο缶幊讨惺且环N面向?qū)ο笥?jì)算機(jī)編程語(yǔ)言的構(gòu)造,描述了所創(chuàng)建的對(duì)象共同的屬性和方法。
- 實(shí)例對(duì)象是根據(jù)某個(gè)類創(chuàng)建的對(duì)象。
- 元類:是一種實(shí)例是類的類。
綜上總結(jié),類是實(shí)例對(duì)象的描述,元類是類對(duì)象的描述。
模型
實(shí)例對(duì)象的存儲(chǔ)結(jié)構(gòu)(以NSObject實(shí)例對(duì)象舉例):
struct NSObject_IMP{
Class isa;
}
其中,isa是指向NSObject類的指針。
類對(duì)象的存儲(chǔ)結(jié)構(gòu)
struct objc_class {
Class _Nonnull isa;
Class _Nullable super_class;
struct objc_ivar_list * _Nullable ivars;
struct objc_method_list * _Nullable * _Nullable methodLists;
struct objc_cache * _Nonnull cache;
struct objc_protocol_list * _Nullable protocols;
...
}
其中,
- isa是指向元類的指針
- super_class是指向父類的指針
- ivars是指向成員變量的指針
- methodLists是指向方法列表的指針
- cache是指向方法緩存的指針
- protocols是指向協(xié)議的指針
關(guān)系
通過(guò)源碼分析,可以確認(rèn)實(shí)例對(duì)象、類和元類是以下關(guān)系:
- 實(shí)例對(duì)象的isa指向類
- 類的isa指向元類
- 元類的isa指向基類的元類
- 類的superclass指向父類。如果沒(méi)有父類,superclass指針為nil
- 元類的superclass指向父類的元類。基類的元類的superclass指向基類
- 實(shí)例對(duì)象調(diào)用實(shí)例方法,是通過(guò)isa找到類,如不存在則通過(guò)superclass找父類
- 類調(diào)用類方法,是通過(guò)isa找元類,如不存在則通過(guò)superclass找父類
消息發(fā)送
消息發(fā)送從類對(duì)象或者元類的方法列表緩存和方法列表中查,沒(méi)有則通過(guò)super指針逐級(jí)向上,有則緩存并調(diào)用。
動(dòng)態(tài)方法解析
開發(fā)者可以實(shí)現(xiàn)以下方法,來(lái)動(dòng)態(tài)添加方法實(shí)現(xiàn):
- +resolveInstanceMethod:
- +resolveClassMethod:
動(dòng)態(tài)解析過(guò)后,會(huì)重新走“消息發(fā)送”的流程,“從receiverClass的cache中查找方法”這一步開始執(zhí)行。
消息轉(zhuǎn)發(fā)
- a轉(zhuǎn)發(fā)給誰(shuí)處理 - (id)forwardingTargetForSelector:(SEL)aSelector{}
- b獲取方法簽名 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{}
- c自定義轉(zhuǎn)發(fā)邏輯 - (void)forwardInvocation:(NSInvocation *)anInvocation{}
延伸問(wèn)題
- 方法模型結(jié)構(gòu)
- 方法緩存什么場(chǎng)景下會(huì)清理
- NSProxy用法