当一个对象接受一个自身不存在的消息时,会报unrecognized selector
Person *p = [[Person alloc] init];
[p performSelector:@selector(dance) withObject:nil];
在此之前其实会走三个步骤,给这个对象三次机会处理这个消息.默认状态是直接报上面的错.
一、resolveInstanceMethod
在这个方法中,可以给当前类添加要执行的方法
+ (BOOL)resolveInstanceMethod:(SEL)sel {
if (sel == @selector(dance)) {
class_addMethod([self class], sel, (IMP)dance, "V@:");
return YES;
}
return [super resolveInstanceMethod:sel];
}
void dance(id self, SEL _cmd){
NSLog(@"dance...");
}
二、forwardingTargetForSelector
这个方法允许我们提供一个能够处理这个消息的对象,让它去处理
//Person.m
- (id)forwardingTargetForSelector:(SEL)aSelector {
if (aSelector == @selector(dance)) {
Dancer *dancer = [[Dancer alloc] init];
return dancer;
}
return [super forwardingTargetForSelector:aSelector];
}
//Dancer.m
- (void)dance {
NSLog(@"Dancer is dancing");
}
上面的代码,我们创建一个能够处理dance消息的对象Dancer,让它去处理这个消息.
三、forwardInvocation
消息重定向
- (void)forwardInvocation:(NSInvocation *)anInvocation {
if ([anInvocation selector] == @selector(dance)) {
Dancer *dancer = [[Dancer alloc] init];
Teacher *teacher = [[Teacher alloc] init];
[anInvocation invokeWithTarget:dancer];
[anInvocation invokeWithTarget: teacher];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
if (aSelector == @selector(dance)) {
return [NSMethodSignature signatureWithObjCTypes:"V@:@"];
}
return [super methodSignatureForSelector:aSelector];
}
它可以自己不实现接受的消息,而让其他对象去实现这个消息.
对比forwardingTargetForSelector返回一个对象,这个方法可以让多个对象执行对应的方法.
网友评论