MST

星途 面试题库

面试题:Objective-C运行时的消息转发机制

详细描述Objective-C运行时的消息转发流程,包括动态方法解析、备用接收者和完整的消息转发这三个主要阶段,每个阶段在什么情况下触发以及具体的操作是什么。
12.7万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

动态方法解析(Dynamic Method Resolution)

  • 触发情况:当向一个对象发送一条它无法识别的消息时,首先会进入动态方法解析阶段。
  • 具体操作
    • 对于实例方法,运行时会调用+ (BOOL)resolveInstanceMethod:(SEL)sel方法,类可以在这个方法中动态添加实例方法的实现。比如通过class_addMethod函数将方法实现添加到类中。
    • 对于类方法,运行时会调用+ (BOOL)resolveClassMethod:(SEL)sel方法,同样可以通过class_addMethod函数添加类方法的实现。如果在这个阶段成功添加了方法实现,消息转发流程结束,消息会被重新发送并得到处理;如果没有添加成功,则进入下一个阶段。

备用接收者(Fast Forwarding)

  • 触发情况:在动态方法解析阶段没有为消息找到处理方法时,会进入备用接收者阶段。
  • 具体操作:运行时会调用- (id)forwardingTargetForSelector:(SEL)aSelector方法。如果该方法返回一个非nil对象,那么这个对象会作为备用接收者来处理这条消息,消息转发流程结束。如果返回nil,则继续进入完整的消息转发阶段。

完整的消息转发(Normal Forwarding)

  • 触发情况:当备用接收者阶段没有找到合适的备用接收者时,进入完整的消息转发阶段。
  • 具体操作
    • 首先,运行时会创建一个NSInvocation对象,该对象包含了原始的消息、目标对象和参数等信息。然后调用- (void)forwardInvocation:(NSInvocation *)anInvocation方法。
    • forwardInvocation:方法中,开发者可以手动将消息转发给其他对象处理。比如找到一个能处理该消息的对象otherTarget,通过[anInvocation setTarget:otherTarget]设置新的目标,然后[anInvocation invoke]来执行消息。
    • 如果forwardInvocation:方法没有处理该消息,运行时会调用- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector方法来获取方法签名。如果该方法返回nil,则会抛出unrecognized selector sent to instance异常;如果返回有效的方法签名,运行时会再次调用forwardInvocation:方法让开发者处理消息。