runtime消息转发有3步:
// [self performSelector:@selector(foo)];
// [self performSelector:@selector(faa)];
// [self performSelector:@selector(fcc)];
1动态方法解析
我们可以在+(BOOL)resolveInstanceMethod:(SEL)sel方法添加一个新的方法
//动态方法解析
- (BOOL)resolveInstanceMethod:(SEL)sel {
if(sel ==@selector(foo)) {
class_addMethod([selfclass], sel, (IMP)fooMethod,@"v");//添加方法
returnYES;
}
return [super resolveInstanceMethod:sel];
}
void fooMethod(id obj,SEL _cmd) {
\
}
2 其他接收者
如果1方法返回NO,就会来到这步,这里我们可以在- (id)forwardingTargetForSelector:(SEL)aSelector给出一个新的接收者
//备用接受者
- (id)forwardingTargetForSelector:(SEL)aSelector {
if(aSelector ==@selector(faa)) {
return [ViewController new];//新的接收者
}
return [super forwardingTargetForSelector:aSelector];
}
3如果第二步返回nil,就来到第三步的完整消息转发
//完整消息转发
//1获取签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
if ([NSStringFromSelector(aSelector) isEqualToString:@"fcc"]) {
return [NSMethodSignature signatureWithObjCTypes:"v@:"];;
}
return [super methodSignatureForSelector:aSelector];
}
//2生成调用对象
- (void)forwardInvocation:(NSInvocation*)anInvocation {
SELsel = anInvocation.selector;
person*p = [personnew];
if ([p respondsToSelector:sel]) {
[anInvocation invokeWithTarget:p];//完整转发
}else{
[self doesNotRecognizeSelector:sel];
}
}