返回

objc_msgSend分析-动态解析+消息转发

IOS

简介

Objective-C作为一门动态语言,消息转发机制是其强大特性的基石。objc_msgSend函数是Objective-C消息发送的底层实现,本文将深入剖析其工作原理,重点关注动态解析和消息转发过程。

<#section>动态解析</#section>

动态解析是在运行时查找方法实现的过程。当对象收到一条消息时,会首先在该对象的类中查找方法实现。如果找不到,就会触发动态解析。

objc_msgSend会依次在以下位置查找方法实现:

  • 当前类的实例方法列表
  • 当前类的类方法列表
  • 当前类的父类的缓存方法列表
  • 当前类的父类的实例方法列表
  • 当前类的父类的类方法列表
  • ...依此向上查找,直到父类为nil

如果在任何一个阶段找到了方法实现,则直接返回该实现。否则,会执行消息转发。

消息转发

如果动态解析失败,objc_msgSend会触发消息转发。消息转发允许对象将消息转发给其他对象或处理程序。

有两种类型的消息转发:

  • 方法转发(method forwarding): 将消息转发给另一个对象,该对象可以处理该消息。
  • 方法不存在(method not found): 消息无法被任何对象处理。

方法转发

方法转发可以通过实现+resolveInstanceMethod:+resolveClassMethod:方法来实现。这些方法用于查找未实现的方法实现并将其添加到类中。

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    // 为未实现的方法添加实现
    Method method = class_addMethod(self, sel, (IMP)myMethod, "v@:");
    return (method != nil);
}

方法不存在

如果方法转发也失败,则会触发方法不存在。可以通过实现-forwardInvocation:方法来处理方法不存在的情况。

- (void)forwardInvocation:(NSInvocation *)invocation {
    // 调用自定义处理程序处理消息
    [myHandler handleInvocation:invocation];
}

结论

动态解析和消息转发机制使Objective-C能够在运行时动态地处理消息。这提供了极大的灵活性,允许对象在不修改源代码的情况下修改其行为。理解这些机制对于编写高效且健壮的Objective-C代码至关重要。