OC底层探索(十四):消息转发

361 阅读2分钟

消息快速转发流程

消息转发顾名思义,是将消息转发给别的接受者,也就是其他的对象 image.png

forwardingTargetForSelector

  • 如果我们也没有实现resolveInstanceMethod,查看log后可以看到之后调用了forwardingTargetForSelector
  • 看一下官方文档的解释

If an object implements (or inherits) this method, and returns a non-nil (and non-self) result, that returned object is used as the new receiver object and the message dispatch resumes to that new object. (Obviously if you return self from this method, the code would just fall into an infinite loop.) If you implement this method in a non-root class, if your class has nothing to return for the given selector then you should return the result of invoking super’s implementation. This method gives an object a chance to redirect an unknown message sent to it before the much more expensive forwardInvocation: machinery takes over. This is useful when you simply want to redirect messages to another object and can be an order of magnitude faster than regular forwarding. It is not useful where the goal of the forwarding is to capture the NSInvocation, or manipulate the arguments or return value during the forwarding.

  • 相当于重定向
  • 可以返回一个新的对象来调用该method
  • 在消耗更多的forwardInvocation:方法之前

image.png

  • WLWPerson 没有实现 look方法,实现forwardingTargetForSelector指定WLWTeacher调用look

消息慢速转发

  • 如果没有实现也forwardingTargetForSelector就会走到methodSigntureForSeletor
  • 官方文档

image.png

  • 通过methodSignatrueForSelector来获得消息的签名来创建一个 NSInvocation对象用来消息转发
  • forwardingInvocation 方法实现消息转发,当然也可以不作处理
  • 官方demo image.png
  • 也可以调用 doesNotRecognizeSelector来实现消息不转发

image.png

源码解析

image.png

  • 打印堆栈发现,消息源码来自 CFFoundation 源码
  • 但是产找源码发现找不对应的代码, 可能是没有开源 image.png
  • 如果想要继续探索,可以通过 image list,找到对应的 CoreFoundtion的可执行文件,然后再通过反汇编的方式进行探索
  • 利用 Hopper 工具,将找到的CoreFoundtion可执行文件拖进去