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函数部分查找-->动态方法解析-->消息转发-->无法解析(报错)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。