resolveInstanceMethod调用两次的两种情况分析 在学习OC消息转发过程中,最常见的流程图就是下面这张了:
但这幅图只是一个大致的流程,在实际调试中,发现在以下两种情况中resolveInstanceMethod方法会调用两次。
第一种情况
通过resolveInstanceMethod断点发现,第二次调用堆栈如下:
在消息转发流程中,当
forwardingTargetForSelector返回nil时就会调methodSignatureForSelector方法,而他的内部触发了class_getInstanceMethod方法
观察
class_getInstanceMethod方法实现,可以发现这里重新执行了方法查找的过程,并且包含了LOOKUP_RESOLVER标志,导致内部执行了第二次resolveInstanceMethod方法
第二种情况
当forwardingTargetForSelector返回self时,并且当methodSignatureForSelector返回值不等于nil的时候,会出现以下堆栈
这个时候由
class_respondsToSelector_inst方法触发了第二次的resolveInstanceMethod方法
总结
- 上面分析了两种
resolveInstanceMethod被二次触发的情况,但是注意第二次方法查找只是用来查询方法是否存在,并没有调用,所以不会出现递归的问题 forwardingTargetForSelector方法是不允许返回self的。