MST

星途 面试题库

面试题:@optional方法与runtime机制的关联

Objective-C运行时(runtime)机制在处理@optional方法时,底层是如何实现的?例如,在消息发送和动态方法解析过程中,@optional方法与@required方法的处理有什么不同?请结合runtime源码进行分析。
40.3万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

1. @optional方法与@required方法的定义

在Objective-C中,协议(protocol)可以定义方法,其中@required(默认,可不写)修饰的方法是必须实现的,而@optional修饰的方法是可选实现的。

2. 消息发送过程

  • 消息结构:在Objective-C中,消息发送是通过objc_msgSend函数实现的。当一个对象接收到一个消息时,运行时会在对象的类的方法列表中查找对应的方法。消息结构主要涉及SEL(方法选择器)和IMP(方法实现指针)。
  • @required方法查找:对于@required方法,在消息发送时,如果对象的类及其父类的方法列表中都没有找到对应的IMP,就会进入动态方法解析阶段。例如,在objc-runtime-new.mmlookUpImpOrForward函数,会先尝试在缓存中查找方法,若未找到则在类的方法列表以及父类方法列表中查找。如果最终还是找不到,就会进入动态方法解析等后续流程。
  • @optional方法查找@optional方法在消息发送时查找流程基本一致,但区别在于即使最终没有找到实现,也不会像@required方法那样导致程序崩溃(在没有进行动态方法解析等补救措施的情况下)。因为@optional方法本身就是可选实现的,所以在运行时找不到实现,程序会继续执行,而不会抛出“unrecognized selector sent to instance”这类错误。

3. 动态方法解析过程

  • 动态方法解析机制:当运行时在方法列表中找不到对应的方法实现时,会进入动态方法解析阶段。类可以通过重写+ (BOOL)resolveInstanceMethod:(SEL)sel(实例方法)或+ (BOOL)resolveClassMethod:(SEL)sel(类方法)来动态添加方法实现。
  • @required方法动态解析:对于@required方法,如果在动态方法解析阶段依然没有成功添加方法实现,就会进入备用接收者和完整转发流程,最终如果还是无法处理该消息,就会导致程序崩溃。
  • @optional方法动态解析@optional方法同样会进入动态方法解析阶段,但即使动态解析没有成功添加方法实现,程序也不会崩溃,而是继续执行,因为它是可选的。例如,在开发中如果一个类遵循了某个协议,但没有实现其中@optional方法,在发送该方法消息时,若动态解析失败,程序不会因这个未实现的@optional方法而崩溃。

通过runtime源码分析可知,@optional方法与@required方法在消息发送和动态方法解析过程中,主要区别在于对未找到方法实现时的处理方式,@optional方法更具灵活性,不会因未实现而导致程序崩溃。