01--方法本質(zhì)05--消息查找流程

對方法的探索,全篇分六個章節(jié)

01-方法本質(zhì)-方法初探

02-方法本質(zhì)-objc_msgSend的使用

03-方法本質(zhì)-面試題分析

04-方法本質(zhì)-lookUpImpOrForward 介紹

05-方法本質(zhì)-消息查找流程

06-方法本質(zhì)-消息轉(zhuǎn)發(fā)流程

五、消息查找流程(重點)

前言

這一章將會介紹消息的第一個流程——查找流程。

當(dāng)調(diào)用一個方法的時候,系統(tǒng)是從哪里找到這個方法的?

[toc]

5.1 lookUpImpOrForward 準(zhǔn)備條件

從源碼中可以看到,有一個 retry:,retry的意思是重試,那么可以猜測出來下面的才是正真的流程,那上面的內(nèi)容是什么呢?

retry上面的兩段代碼,_class_initializerealizeClass,不是初始化就是準(zhǔn)備,可以猜測這里是一些變量的準(zhǔn)備條件

再往上面走,看到有一個 runtimeLock。lock(); 方法,而且還有很多注釋,說明這段代碼在這個方法里面有很重要的作用。仔細(xì)扒一扒這些注釋的含義,

  • 注釋一:講了運行時鎖的作用,防止多線程發(fā)生資源搶奪

    runtimeLock在isrealize和isInitialized檢查過程中被持有,以防止對并發(fā)實現(xiàn)的競爭。

  • 注釋二:講了為什么要添加運行時鎖。舉了一個例子,在緩存中搜索方法的時候(讀操作),分類可以刷新緩存(寫操作),同時對一塊內(nèi)存進(jìn)行讀寫操作,它是受不了的。

    runtimeLock在方法搜索過程中保持,使方法查找+緩存填充原子相對于方法添加。否則,可以添加一個類別,但是會無限期地忽略它,因為在代表類別的緩存刷新之后,緩存會用舊值重新填充。

繼續(xù)往上面走,有一個 return imp; 代碼。這個方法本來就是查找一個方法的,能 return 的話,說明這個方法找到了。這里的代碼很簡單,就是從緩存里面找到了方法。

有趣的是這段代碼的注釋--// Optimistic cache lookup(樂觀的緩存查找)。這就有意思了,什么叫樂觀的,我們程序員講究的是嚴(yán)謹(jǐn)?shù)模茨苷业揭床荒苷业?,既然是樂觀的,我們就不用去分析他了。

再往上面走就是一些變量的創(chuàng)建,沒什么好分析的。

到這里,我們對 lookUpImpOrForward 方法已經(jīng)分析了一半了,下面來看另外一半流程。

5.2 lookUpImpOrForward 查找流程

5.2.1 lookUpImpOrForward 流程圖

image

5.2.2 lookUpImpOrForward 流程分析

retry 開始分析

1、從類的緩存查找,如果找到IMP,則跳到Done,返回IMP
imp = cache_getImp(cls,sel);

2、從類的方法列表查找
Method meth = getMethodNoSuper_nolock(cls,sel);

  • 查找算法:二分查找
  • 如果找到,則填充緩存,跳到Done,返回IMP
    log_and_fill_cache(cls,meth->imp,sel,inst,cls);

遍歷父類

for (Class curClass = cls->superclass;
              curClass != nil;
              curClass = curClass->superclass)

3、從父類的緩存查找
imp = cache_getImp(curClass,sel);

  • 如果在父類中找到方法,則將方法緩存到當(dāng)前類,下次可以直接從緩存取
  • 跳到Done,返回IMP
    log_and_fill_cache(cls,imp,sel,inst,curClass);

4、從父類的方法列表查找
Method meth = getMethodNoSuper_nolock(curClass,sel);

  • 查找算法:二分查找
  • 如果找到,則填充緩存
  • 跳到Done,返回IMP
    log_and_fill_cache(cls,meth->imp,sel,inst,curClass);

5、方法動態(tài)決議流程
_class_resolveMethod(cls,sel,inst);

6、消息轉(zhuǎn)發(fā)流程
imp = (IMP)_objc_msgForward_impcache;

5.3 總結(jié)

  1. 為什么分析 lookUpImpOrForward 方法。
  2. 怎么分析 lookUpImpOrForward 方法。
  3. retry 前做了什么事。
  4. retry 后的流程是什么樣的。
  5. lookUpImpOrForward 查找流程圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容