返回

iOS 底层探索篇 —— 方法的转发流程

见解分享

在之前的文章《iOS 底层探索篇 —— 方法的查找流程》中,我们了解了方法的查找流程。如果方法没有查找到,在 lookUpImpOrForward() 函数中还有一部分是留给查找失败的处理。接下来,我们开始分析以下两个流程:

  1. 函数入口
  2. 解析方法
  3. 对象与类方法的转发

1. 函数入口

当方法查找失败时,lookUpImpOrForward() 函数会根据不同的情况调用不同的函数进行处理。

  • 如果是对象方法,则调用 object_forwardImp() 函数。
  • 如果是类方法,则调用 class_forwardImp() 函数。

这两个函数的作用都是将消息转发给另一个对象或类。

2. 解析方法

object_forwardImp()class_forwardImp() 函数中,首先会解析消息中的选择器。选择器是一个字符串,它标识了要调用的方法。

解析选择器后,会根据选择器的名称和参数类型来查找相应的方法。如果找到相应的方法,则直接调用该方法。如果找不到相应的方法,则会继续进行转发。

3. 对象与类方法的转发

对象方法和类方法的转发流程略有不同。

3.1 对象方法的转发

对象方法的转发流程如下:

  1. 首先,会检查对象是否实现了 forwardingTargetForSelector: 方法。如果实现了该方法,则调用该方法来获取要转发的目标对象。
  2. 如果没有实现 forwardingTargetForSelector: 方法,或者该方法返回 nil,则会检查对象是否实现了 methodSignatureForSelector: 方法。如果实现了该方法,则调用该方法来获取方法签名。
  3. 如果没有实现 methodSignatureForSelector: 方法,或者该方法返回 nil,则会检查对象是否实现了 respondsToSelector: 方法。如果实现了该方法,则调用该方法来检查对象是否响应选择器。
  4. 如果对象不响应选择器,则会抛出 NSInvalidArgumentException 异常。

3.2 类方法的转发

类方法的转发流程如下:

  1. 首先,会检查类是否实现了 forwardingClassForSelector: 方法。如果实现了该方法,则调用该方法来获取要转发的目标类。
  2. 如果没有实现 forwardingClassForSelector: 方法,或者该方法返回 nil,则会检查类是否实现了 methodSignatureForSelector: 方法。如果实现了该方法,则调用该方法来获取方法签名。
  3. 如果没有实现 methodSignatureForSelector: 方法,或者该方法返回 nil,则会检查类是否实现了 respondsToSelector: 方法。如果实现了该方法,则调用该方法来检查类是否响应选择器。
  4. 如果类不响应选择器,则会抛出 NSInvalidArgumentException 异常。

总结

以上就是 iOS 系统中方法转发的流程。通过了解这些流程,我们可以更好地理解 iOS 消息发送和处理的底层机制。