OC 消息转发中resolveInstanceMethod调用两次的问题

591 阅读1分钟

resolveInstanceMethod调用两次的两种情况分析 在学习OC消息转发过程中,最常见的流程图就是下面这张了: image.png

但这幅图只是一个大致的流程,在实际调试中,发现在以下两种情况中resolveInstanceMethod方法会调用两次。

第一种情况

通过resolveInstanceMethod断点发现,第二次调用堆栈如下:

image.png 在消息转发流程中,当forwardingTargetForSelector返回nil时就会调methodSignatureForSelector方法,而他的内部触发了class_getInstanceMethod方法

image.png 观察class_getInstanceMethod方法实现,可以发现这里重新执行了方法查找的过程,并且包含了LOOKUP_RESOLVER标志,导致内部执行了第二次resolveInstanceMethod方法

第二种情况

forwardingTargetForSelector返回self时,并且当methodSignatureForSelector返回值不等于nil的时候,会出现以下堆栈 image.png 这个时候由class_respondsToSelector_inst方法触发了第二次的resolveInstanceMethod方法

image.png

总结

  1. 上面分析了两种resolveInstanceMethod被二次触发的情况,但是注意第二次方法查找只是用来查询方法是否存在,并没有调用,所以不会出现递归的问题
  2. forwardingTargetForSelector方法是不允许返回self的。