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函数部分查找-->动态方法解析-->消息转发-->无法解析(报错)

你可能感兴趣的:(IOS Runtime之objc_msgSend方法查找)