IOS Runtime之objc_msgSend方法查找

源碼解析

1、查看源碼,發現objc_msgSend是從匯編中開始的。

image.png

2、 如果指針小于等于LNilOrTagged,直接return返回。

image.png

3、 通過isa找到相應的class。

image.png

4、 由上圖可知,接下來CacheLookup(宏定義)找NORMAL參數。

image.png

4.1、CacheHit
image.png

  • NORMAL
  • GETIMP 直接返回對應的參數
  • LOOKUP

4.2、CheckMiss 找不到的情況
image.png

  • NORMAL --> LGetImpMiss
    1、沒有相應的緩存
    2、在MethodTableLookup方法列表查找
    3、在__class_lookupMethodAndLoadCache3匯編查找
    4、在__class_lookupMethodAndLoadCache3 C函數查找
_class_lookupMethodAndLoadCache3

4.1、imp = cache_getImp(cls,sel); --> 回到之前的CacheLookup

4.2、判斷配置

4.3、核心--retry

__4.3.1、cache_getImp又去拿一次(因為OC是動態語言,隨時可以操作修改,防止數據問題)
__4.3.2、getMethodNoSuper_nolock從自己類的方法列表去找,找到了就緩存。
__4.3.3、遞歸去查找父類方法,直到NSObject,找到了就緩存。

4.4、如果還是找不到 -->
image.png
  • GETIMP --> __objc_msgSend_uncached
  • LOOKUP --> __objc_msgLookup_uncached

5、動態方法解析

  • class_resolveMethod
image.png

1、_class_resolveInstanceMethod
2、_class_resolveClassMethod

6、消息轉發

消息轉發流程.png

7、總結

  • 方法查找流程大致如下
    匯編部分查找-->C函數部分查找-->動態方法解析-->消息轉發-->無法解析(報錯)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。