消息转发两个阶段
- 先征询接收者,所属的类,看其是否能动态添加方法,已处理当前这个“未知的选择子”(unknow selector),这叫做动态解析(dynamic method resolution)。
- 完整地消息转发机制(full forwarding mechanism)
动态方法解析
对象收到无法解读的消息后,首先调用其所属类的下列类方法:
/*
* @param SEL 未知的选择子
* @return BOOL 表示该类是否能新增一个实例方法用以处理此选择子
*/
+ (BOOL)resolveInstanceMethod:(SEL)selector;
假如尚未实现的方法不是实例方法而是类方法,运行期系统就会调用另一个方法:
+ (BOOL)resolveClassMethod:(SEL)selector;
备援接受者
当前接收者还有第二次机会处理未知的选择子,在这一步中,运行期系统会问它:能不能把这条消息转发给其它接收者处理。
- (id)forwardingTargetForSelector:(SEL)selector;
完整的消息转发
- 创建NSInvocation对象,把与尚未处理的那条消息有关的全部细节都封装于其中。此对象包含选择子、目标及参数。
- 消息派发系统会将NSInvocation对象指派给目标对象,此步骤会调用:
- (void)forwardInvocation:(NSInvocation*)invocation;
这样从子类不命中调用超类,直至NSObject。如果最后调用NSObject类的方法,那么紧接着会抛出异常“doesNotRecognizeSelector”,以抛出异常。