面试题答案
一键面试方法动态解析流程
- 动态方法解析:当对象接收到无法识别的消息时,首先进入动态方法解析阶段。
- 实例方法:运行时会调用类的
+ (BOOL)resolveInstanceMethod:(SEL)sel
类方法。如果实现了该方法,并在其中通过class_addMethod
函数动态添加了对应SEL
的实例方法,那么消息发送就会成功,程序继续执行新添加的方法。 - 类方法:运行时会调用类的
+ (BOOL)resolveClassMethod:(SEL)sel
类方法。若实现此方法,并在其中动态添加对应SEL
的类方法,消息发送成功,程序执行新添加的类方法。
- 实例方法:运行时会调用类的
- 备用接收者:如果动态方法解析没有处理该消息,接下来进入备用接收者阶段。运行时会调用
- (id)forwardingTargetForSelector:(SEL)aSelector
实例方法。如果实现了该方法,并返回一个能处理该SEL
的对象,那么消息会转发给这个备用对象处理。 - 完整的消息转发:若备用接收者阶段也未处理消息,进入完整的消息转发阶段。
- 首先,运行时会创建一个
NSInvocation
对象,封装消息的参数和返回值等信息,然后调用- (void)forwardInvocation:(NSInvocation *)anInvocation
实例方法。在该方法中,可以手动指定将消息转发给其他对象处理。 - 如果
forwardInvocation:
方法未实现或未正确处理消息,最后会调用- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
实例方法来获取方法签名。若获取到有效的方法签名,forwardInvocation:
方法会再次被调用进行消息转发;若未获取到有效签名,程序会抛出NSInvalidArgumentException
异常,提示无法识别的选择器。
- 首先,运行时会创建一个