MST
星途 面试题库

面试题:Objective-C消息发送机制的基本流程

请描述Objective-C中消息发送机制的基本流程,从代码中向对象发送消息开始,到最终执行相应方法结束,涉及哪些关键步骤?
24.7万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试
  1. 消息发送阶段
    • 当代码中向对象发送消息,例如 [obj someMethod] 时,编译器首先将其转化为 objc_msgSend 函数调用。objc_msgSend 函数第一个参数是接收者对象(即 obj),第二个参数是方法选择器(@selector(someMethod)),后面跟着方法的参数。
    • 运行时系统首先在接收者对象的类的缓存(cache)中查找方法。缓存是一个哈希表,通过方法选择器作为键来快速查找对应的方法实现。如果在缓存中找到,则直接调用该方法实现,流程结束。
  2. 动态方法解析阶段
    • 如果在缓存中未找到方法,运行时系统会在类的方法列表(methodLists)中查找。方法列表存储了类中所有的实例方法(对于类方法,则在元类的方法列表中查找)。如果在方法列表中找到方法实现,则将其缓存起来,并调用该方法,流程结束。
    • 若在方法列表中也未找到,进入动态方法解析阶段。运行时会调用 + (BOOL)resolveInstanceMethod:(SEL)sel 方法(对于实例方法,类方法则调用 + (BOOL)resolveClassMethod:(SEL)sel)。在这个方法中,开发者可以动态添加方法实现。如果成功添加并返回 YES,则重新进行消息发送流程;如果返回 NO,进入备用接收者阶段。
  3. 备用接收者阶段
    • 若动态方法解析未找到方法,运行时会调用 -(id)forwardingTargetForSelector:(SEL)aSelector 方法,允许对象指定一个备用的对象来处理该消息。如果返回一个非 nil 的对象,运行时会向这个备用对象重新发送消息。若返回 nil,进入完整的消息转发阶段。
  4. 完整的消息转发阶段
    • 运行时会创建一个 NSInvocation 对象,它包含了原始的消息发送信息,如方法选择器、参数等。然后调用 -(void)forwardInvocation:(NSInvocation *)anInvocation 方法。在这个方法中,开发者可以手动指定如何处理这个消息,例如转发给其他对象等。如果没有处理,最终会调用 doesNotRecognizeSelector: 方法,抛出 NSInvalidArgumentException 异常,程序崩溃。