如果既不动态生成方法实现,也不转发给能处理的备选接收者,最后还有一个解决方案。那你写一个方法的详细报告,对组织说明这个活的详细细节是什么,上交这份报告(NSInvocation)给组织,组织给你处理。
//消息转发第三部 完整的消息转发
- (void)forwardInvocationNSInvocation *)anInvocation{
if ([Developer instancesRespondToSelector:anInvocation.selector]) {
Developer *dev = [[Developer alloc] init"Huang"];
[anInvocation invokeWithTarget:dev];
}
}
//person找不到developer相关的方法,就是因为这个函数找不到方法的实现签名引发了崩溃,我们这里需要给aSelector新建方法签名 再交给Developer对象去处理
- (NSMethodSignature *)methodSignatureForSelectorSEL)aSelector{
NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
if (!signature) {
//不签名会崩溃
//判断实现类的实例是否有这个方法 有则签名这个方法 保证能正确转发
if ([Developer instancesRespondToSelector:aSelector]) {
signature = [Developer instanceMethodSignatureForSelector:aSelector];
}
//直接签名
// if ([NSStringFromSelector(aSelector) hasPrefix"developer"]) {
// signature = [NSMethodSignature signatureWithObjCTypes:"v@:"];
// }
}
return signature;
}
组织要处理呀,不处理就革命了。拿到方法的细节封装NSInvocation对象之前,组织需要知道为啥会上传报告,通过methodSignatureForSelector,发现组织的科技树(方法签名)里面没有developer相关的技能,所以干不了这个活。那么既然科技树里面没有developer相关技能,那么我们就要先点亮科技树才行,所以我们给developer前缀的方法进行方法签名。点亮科技树。
然后forwardInvocation中,把报告交给能干这个活的人,完成消息转发,结束。
根据实际的情况决定怎么处理NSInvocation对象,本Demo只是简单地把NSInvocation交给了备选接收者处理。
总结
如果一个对象无法响应一个方法,那么就会进入消息转发机制
第一步,我们可以动态创建一个方法实现去响应这个消息,消息转发结束
第一步未处理,第二步我们可以选择一个备选的消息接收者去处理这个消息
第二步未实现,最后一步第三步,启动完整的消息转发机制,处理方法签名,实现NSInvocation对象转发。
最好在第一步处理,次之第二步,如果第三步只是使用备选接收者处理,还不如直接第二步快速处理结束,毕竟第三步需要方法签名和封装NSInvocation。 |