消息转发分为两个阶段
--第一阶段,先问接受者所属的类,能否动态添加方法处理当前“未知的选择器”,这叫做“动态方法解析”。
--第二阶段,“完整的消息转发机制”,首先请接受者看看有没有其他对象能处理这条消息,如果有,则把消息转给那个对象,消息转发过程结束。如果没有“备用接受者”,则启动完整的消息转发机制,系统会把与消息有关的所有细节封装到 NSInvocation对象中,再给接受者最后一次机会处理当前消息。
动态方法解析
该方法参数是那个未知的选择器,返回值是bool类型,表示这个类是否能新增一个实例方法处理这个选择器。有机会新增一个处理此选择器的方法。如果未实现的方法不是实例方法而是类方法。运行期系统就会调用另一个方法。
备注:使用这种方法的前提是,相关实现代码已经写好,只等运行时动态插在类里。
备用接受者
当前接受者还有第二次机会处理未知的选择器。能不能把这条消息转给其他对象处理。
在一个对象内部,可能还有一系列其他对象,该对象可经由此方法将能够处理某选择子的相关内部对象返回。
备注:在这一步,无法操作所转发的消息。
完整的消息转发
首先创建NSInvocation对象,把尚未处理的消息所有相关细节都封装其中。包含选择器、目标、参数。
实现方式:在触发消息前,先以某种方式改变消息内容,比如,追加另外一个参数,或者改变选择器。
实现此方法时,如果发现调用操作不应该由本类操作,则调用父类同名方法。继承体系中每个类都有机会处理此调用请求,直到NSObject。最后调用了NSObject类的方法,该方法会继续调用“doesNotRecognizeSelector:”,抛出异常,代表消息最终未被处理。
消息转发全流程
步骤越往后,处理消息的代价越大。最好能在第一步处理完,运行期系统就可以将此方法缓存。第三部只是修改了调用目标,这项改动放在第二步会更简单,不然的话,还得创建并处理完整的NSInvocation。
总结:
--1.若对象无法响应某个选择子,则进入消息转发流程。
--2.通过运行期的动态方法解析功能,我们可以在需要用到某个方法时再将其加入类中。
--3.对象可以把其无法解读的某些选择子转交给其他对象来处理。
--4.如果还没办法处理选择子,那就启动完整的消息转发机制。
--第一阶段,先问接受者所属的类,能否动态添加方法处理当前“未知的选择器”,这叫做“动态方法解析”。
--第二阶段,“完整的消息转发机制”,首先请接受者看看有没有其他对象能处理这条消息,如果有,则把消息转给那个对象,消息转发过程结束。如果没有“备用接受者”,则启动完整的消息转发机制,系统会把与消息有关的所有细节封装到 NSInvocation对象中,再给接受者最后一次机会处理当前消息。
动态方法解析
+(BOOL)resolveInstanceMethod:(SEL)sel
该方法参数是那个未知的选择器,返回值是bool类型,表示这个类是否能新增一个实例方法处理这个选择器。有机会新增一个处理此选择器的方法。如果未实现的方法不是实例方法而是类方法。运行期系统就会调用另一个方法。
+(BOOL)resolveClassMethod:(SEL)sel
备注:使用这种方法的前提是,相关实现代码已经写好,只等运行时动态插在类里。
备用接受者
当前接受者还有第二次机会处理未知的选择器。能不能把这条消息转给其他对象处理。
-(id)forwardingTargetForSelector:(SEL)aSelector
在一个对象内部,可能还有一系列其他对象,该对象可经由此方法将能够处理某选择子的相关内部对象返回。
备注:在这一步,无法操作所转发的消息。
完整的消息转发
首先创建NSInvocation对象,把尚未处理的消息所有相关细节都封装其中。包含选择器、目标、参数。
-(void)forwardInvocation:(NSInvocation *)anInvocation
实现方式:在触发消息前,先以某种方式改变消息内容,比如,追加另外一个参数,或者改变选择器。
实现此方法时,如果发现调用操作不应该由本类操作,则调用父类同名方法。继承体系中每个类都有机会处理此调用请求,直到NSObject。最后调用了NSObject类的方法,该方法会继续调用“doesNotRecognizeSelector:”,抛出异常,代表消息最终未被处理。
消息转发全流程
步骤越往后,处理消息的代价越大。最好能在第一步处理完,运行期系统就可以将此方法缓存。第三部只是修改了调用目标,这项改动放在第二步会更简单,不然的话,还得创建并处理完整的NSInvocation。
总结:
--1.若对象无法响应某个选择子,则进入消息转发流程。
--2.通过运行期的动态方法解析功能,我们可以在需要用到某个方法时再将其加入类中。
--3.对象可以把其无法解读的某些选择子转交给其他对象来处理。
--4.如果还没办法处理选择子,那就启动完整的消息转发机制。