iOS爱上底层-消息查找流程

290 阅读1分钟

查找流程汇编部分

首先我们在main函数中创建一个类,并且实现类中的一个方法,然后开启汇编显示模式。
然后我们按住control+step into进入objc_msgSend。

我们会发现他在最后调用了_objc_msgSend_uncached,我们再次以同样的方法进入_objc_msgSend_uncached。

可以清楚的看见,在_objc_msgSend_uncached之后是调用了_class_lookupMethodAndLoadCache3,并且是有源码的,接下来我们进入源码部分看看。

查找流程源码部分

在Xcode中搜索_class_lookupMethodAndLoadCache3,并选择搜索结果中的第一个,然后选择右边的api,看看接下来做了什么。

我们再次进入lookUpImpOrForward(),看看这里面干了什么。
消息查找源码分析:在retry上面的代码是为了给下面的查找流程做准备工作。主要还是得看下面:
上图中的getMethodNoSuper_nolock会在下面单独解析。

_class_resolveMethod会在下面进行分析。

getMethodNoSuper_nolock 方法解析:

_class_resolveMethod 动态消息转发

当系统在父类也没有找到sel的时候,就会进入动态消息转发。此时我们进入_class_resolveMethod看一下源码:

首先会判断cls是不是元类,如果不是,就是对象方法,会调用_class_resolveInstanceMethod,如果是,就是类方法,会调用_class_resolveClassMethod方法。
_class_resolveInstanceMethod源码解析:
_class_resolveClassMethod源码解析:

总结

1、如果objc_msgSend中没有缓存,则会进入class_lookupMethodAndLoadCache3 进行慢速递归查找
2、实例方法会在类中查找,类方法会在元类中查找,如果都没有找到,就会去自己的父类中查找
3、如果都没有找到,系统会判断开发者是否进行了动态消息转发,如果复写了就进入消息转发,如果没则会进入_objc_msgForward_impcache。