在Objective-C中,如果你将一个没有实现的消息发送给一个接受者,系统会调用接受者forwardInvocation:方法,从而给这个接受者一个二次处理的机会。机遇这个特性,我们可以做一些自己的处理。
例如下面的调用,我们调用了一个不存在的方法,系统就会调用myObject对象的forwardInvocation:方法。
objc_msgSend(self, @selector(didnotexistmethod:)
-(void) forwardInvocation:(NSInvocation *)anInvocation
{
NSLog(@"test");
SEL sel = [anInvocation selector];
NSLog(@"forwardInvocation, %s", sel_getName(sel));
NSInteger numberAug = [[anInvocation methodSignature] numberOfArguments];
NSLog(@"arg number:%d", numberAug);
MyObject* myobj = [[MyObject alloc] init];
if ([myobj respondsToSelector:sel])
{
//[anInvocation setArgument:(void*)"it's a test param" atIndex:2];
[anInvocation invokeWithTarget:myobj];
}
else
{
[super forwardInvocation:anInvocation];
}
}
-(void)oneParamMethod:(NSArray*)param
{
NSLog(@"oneParamMethod");
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
NSMethodSignature* sig = [ViewController instanceMethodSignatureForSelector:@selector(oneParamMethod:)];
return sig;
//return [NSMethodSignature signatureWithObjCTypes:"@^v^ci"];
}
实现代码如上所示,为了forwardInvocation方法能被正确的调用,我们必须实现methodSignatureForSelector:方法。
然后我们在MyObject中实现如下, param就是我们在调用的时候传递的参数。
-(void) didnotexistmethod:(id)param
{
NSLog(@"MyObject didnotexistmethod is called");
}