Object-C是一门C的超集的动态语言,内部的函数调用不叫调用而叫做消息转发,今天我们看看在执行函数时遇到无法识别的函数如何接盘?
代码语言:javascript复制@implementation Person
-(void)sayHello{
[self performSelector:@selector(xx)];
}
(BOOL)resolveInstanceMethod:(SEL)sel{
if ([NSStringFromSelector(sel) isEqualToString:@"xx"]) {
return NO;
}
return true;
}
@end
第一接盘机会
在OC中执行一个函数的时候,会后首先检测是否能响应这个SEL动作,假如实例没有实现,系统会帮忙转发一次给一个替补人员来做这个事情
代码语言:javascript复制/**
将为未被实现的转移给了一个备用的类,加入能够响应了错误就不再往下传递
@param aSelector 未被实现的函数
@return 能够响应这个未被实现的函数的实例
*/
-(id)forwardingTargetForSelector:(SEL)aSelector{
if ([NSStringFromSelector(aSelector) isEqualToString:@"xx"]) {
Helper *helper = [[Helper alloc] init];
return helper;
}
return nil;
}
第二次接盘
当系统尝试通过转发时没有提供备选的选手接盘的时候,怎么办呢?咱们的系统依然不死心想再给一次机会-----wei,在座的观众有谁会这道题啊?
于是乎观众席上引论纷纷,路人甲此时举手啦,不过现场的执行人员说你说会就会,不过我们要登记一下,要是到时候抽奖需要把你名字放奖池里面啊……于是乎就出现了工作人员在上台表演之时顺便给路人甲说说参与规则注意事项----签名
代码语言:javascript复制//下面两方法是一个整体,为啥呢?因为只有有了方法签名才会走forwardInvocation
-(void)forwardInvocation:(NSInvocation *)anInvocation{
if ([Helper instancesRespondToSelector:anInvocation.selector]) {
[anInvocation invokeWithTarget:[[Helper alloc]init] ];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
return nil;
NSMethodSignature * signature = [super methodSignatureForSelector:aSelector];
if (signature == nil) {
//检测是否能响应函数,然后将方法签名给对应class
//Returns an NSMethodSignature object that contains a description of the instance method identified by a given selector.
if([Helper instancesRespondToSelector:aSelector]){
signature = [Helper instanceMethodSignatureForSelector:aSelector];
}
}
return signature;
}
假如后援调动了,观众参与了依然没有解决问题,那么不好意思啦,这个事情没法办啦----抛出异常让整个事件干不下去
根据需要设计的接盘侠
代码语言:javascript复制@interface Helper:NSObject
@end
@implementation Helper
-(void)xx{
NSLog(@"接盘侠");
}
@end