類(lèi)查找
先查找類(lèi)中的方法然后再查找分類(lèi)方法堰氓,分類(lèi)中的方法會(huì)添加到類(lèi)中的方法列表后面
lookUpImpOrForward
- 以下通過(guò)斷點(diǎn)調(diào)試的方式進(jìn)行查找
當(dāng)對(duì)象調(diào)用方法時(shí)會(huì)調(diào)用objc_msgSend
中先進(jìn)行判斷在緩存中是否存在,如果不存在將會(huì)走到_objc_msgSend_uncached
未緩存中查找
此時(shí)我們使用斷點(diǎn)進(jìn)入就可以看到氯材,進(jìn)入objc_msgSend_uncached
中時(shí)調(diào)用了lookUpImpOrForward
方法针史,全局搜索lookUpImpOrForward
方法可以知道該方法是一個(gè)C++方法,可以查到具體的實(shí)現(xiàn),此時(shí)我們就知道在調(diào)用objc_msgSend
后主要現(xiàn)在該方法中進(jìn)行了方法的判斷處理蔗喂。
查找思路:查找方式是什么,條件是什么高帖,缰儿,返回什么?
- 查找方式是什么散址?
在lookUpImpOrForward
方法中乖阵,首先調(diào)用一個(gè)_objc_msgForward_impcache
方法,通過(guò)調(diào)試匯編進(jìn)行查找可以找到
是在緩存中逐級(jí)進(jìn)行消息轉(zhuǎn)發(fā)找到一個(gè)目標(biāo)進(jìn)行處理预麸,然后初始化一個(gè)臨時(shí)的`imp = nil; Class = curClass;
當(dāng)函數(shù)調(diào)用走到該判斷語(yǔ)句時(shí)瞪浸,需要解釋一個(gè)behavior
參數(shù),通過(guò)匯編可以看到參數(shù) behavior
是通過(guò)LOOLUP_INITIALIZE = 1
與 LOOKUP_RESOLVER = 2
通過(guò)|
按位或的方式進(jìn)行獲得吏祸,此時(shí)behavior
的值為3
对蒲。
而
LOOKUP_CACHE = 4
,因此此時(shí)不會(huì)進(jìn)入緩存中進(jìn)行快速查找贡翘,接下來(lái)是對(duì)條件的一些判斷比如類(lèi)的初始化等此處略過(guò)蹈矮。
首先調(diào)用了
Method meth = getMethodNoSuper_nolock()
,該方法的主要作用是通過(guò)二分查找的方式在當(dāng)前類(lèi)的方法列表中進(jìn)行二分查找鸣驱,主要用到的方法如下因?yàn)?code>objc_class 中的class_data_bits_t bits
中的class_rw_t data
包含了類(lèi)的屬性
泛鸟,方法
和協(xié)議
,所以可以調(diào)用相關(guān)方法來(lái)獲取當(dāng)前類(lèi)的全部實(shí)例方法踊东。
在該方法中就是通過(guò)使用指針來(lái)進(jìn)行二分查找谈况,在當(dāng)前的方法列表中進(jìn)行查找。
如果查找到了递胧,把找到的函數(shù)指針地址給到當(dāng)前臨時(shí)變量imp
,并走到
done:
log_and_file_cache(cls, imp, sel, inst, curClass);
通過(guò)內(nèi)部的調(diào)用cache_t
中的insert
方法碑韵,把當(dāng)前方法插入到緩存的適當(dāng)位置,至于是如何插入的缎脾,緩存是如何分配的可以查看cache_t講解祝闻。
如果內(nèi)有找到將進(jìn)行在父類(lèi)中逐級(jí)查找的方式進(jìn)行查找,如果最后找到根類(lèi)NSObject
還是沒(méi)有找到,將把forward_imp
賦值給imp
來(lái)進(jìn)行消息轉(zhuǎn)發(fā)联喘。
在這段代碼中
LOOKUP_RESOLVER = 2
华蜒,調(diào)用resolveMethod_locked
方法然后就是在
resolveInstanceMethod
方法中進(jìn)行處理。此時(shí)我們就可以重寫(xiě)
resolveInstanceMethod
方法豁遭,在該方法中為未實(shí)現(xiàn)的函數(shù)進(jìn)行設(shè)置目標(biāo)對(duì)象和函數(shù)叭喜。如果沒(méi)有進(jìn)行處理將進(jìn)行消息轉(zhuǎn)發(fā)。
消息轉(zhuǎn)發(fā)流程
擴(kuò)展
- 在進(jìn)行二分查找時(shí)是優(yōu)先在分類(lèi)中查找而不是在本類(lèi)中