源码解析
1、查看源码,发现objc_msgSend是从汇编中开始的。
![](https://img.haomeiwen.com/i15598225/87815ea977e95099.png)
2、 如果指针小于等于LNilOrTagged,直接return返回。
![](https://img.haomeiwen.com/i15598225/d5f2910d38353ea4.png)
3、 通过isa找到相应的class。
![](https://img.haomeiwen.com/i15598225/5beb53e5db9d759a.png)
4、 由上图可知,接下来CacheLookup(宏定义)找NORMAL参数。
![](https://img.haomeiwen.com/i15598225/a3e2166b2482840c.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.4、如果还是找不到 -->
__4.3.2、getMethodNoSuper_nolock从自己类的方法列表去找,找到了就缓存。
__4.3.3、递归去查找父类方法,直到NSObject,找到了就缓存。
image.png
- GETIMP --> __objc_msgSend_uncached
- LOOKUP --> __objc_msgLookup_uncached
5、动态方法解析
- class_resolveMethod
image.png
1、_class_resolveInstanceMethod
2、_class_resolveClassMethod
6、消息转发
![](https://img.haomeiwen.com/i15598225/e4095b3936637058.png)
7、总结
- 方法查找流程大致如下
汇编部分查找-->C函数部分查找-->动态方法解析-->消息转发-->无法解析(报错)
网友评论