返回
iOS 底层探索篇 —— 方法的转发流程
见解分享
2023-12-27 18:39:38
在之前的文章《iOS 底层探索篇 —— 方法的查找流程》中,我们了解了方法的查找流程。如果方法没有查找到,在 lookUpImpOrForward()
函数中还有一部分是留给查找失败的处理。接下来,我们开始分析以下两个流程:
- 函数入口
- 解析方法
- 对象与类方法的转发
1. 函数入口
当方法查找失败时,lookUpImpOrForward()
函数会根据不同的情况调用不同的函数进行处理。
- 如果是对象方法,则调用
object_forwardImp()
函数。 - 如果是类方法,则调用
class_forwardImp()
函数。
这两个函数的作用都是将消息转发给另一个对象或类。
2. 解析方法
在 object_forwardImp()
和 class_forwardImp()
函数中,首先会解析消息中的选择器。选择器是一个字符串,它标识了要调用的方法。
解析选择器后,会根据选择器的名称和参数类型来查找相应的方法。如果找到相应的方法,则直接调用该方法。如果找不到相应的方法,则会继续进行转发。
3. 对象与类方法的转发
对象方法和类方法的转发流程略有不同。
3.1 对象方法的转发
对象方法的转发流程如下:
- 首先,会检查对象是否实现了
forwardingTargetForSelector:
方法。如果实现了该方法,则调用该方法来获取要转发的目标对象。 - 如果没有实现
forwardingTargetForSelector:
方法,或者该方法返回nil
,则会检查对象是否实现了methodSignatureForSelector:
方法。如果实现了该方法,则调用该方法来获取方法签名。 - 如果没有实现
methodSignatureForSelector:
方法,或者该方法返回nil
,则会检查对象是否实现了respondsToSelector:
方法。如果实现了该方法,则调用该方法来检查对象是否响应选择器。 - 如果对象不响应选择器,则会抛出
NSInvalidArgumentException
异常。
3.2 类方法的转发
类方法的转发流程如下:
- 首先,会检查类是否实现了
forwardingClassForSelector:
方法。如果实现了该方法,则调用该方法来获取要转发的目标类。 - 如果没有实现
forwardingClassForSelector:
方法,或者该方法返回nil
,则会检查类是否实现了methodSignatureForSelector:
方法。如果实现了该方法,则调用该方法来获取方法签名。 - 如果没有实现
methodSignatureForSelector:
方法,或者该方法返回nil
,则会检查类是否实现了respondsToSelector:
方法。如果实现了该方法,则调用该方法来检查类是否响应选择器。 - 如果类不响应选择器,则会抛出
NSInvalidArgumentException
异常。
总结
以上就是 iOS 系统中方法转发的流程。通过了解这些流程,我们可以更好地理解 iOS 消息发送和处理的底层机制。