一般情况下方法的调用都是用 performSelector:withObject执行方法的调用。但是当参数的数量比较的多的时候,这种方法就不能简单的满足我们的需求的时候,我们就需要用到NSInvocation这个类了
首先NSInvocation只能使用系统提供的类方法来初始化实例,而不是alloc/init,对于初始化后的实例 我们要为其设置target、selector、argument(需要参数的时候设置)
代码是亲自试过的。。。
1.不带参数的NSIvocation的简单调用
- (void)viewDidLoad {
[superviewDidLoad];
SEL selector =@selector(say);
//创建一个函数签名这里的函数签名可以是任意的,但是需要注意 函数签名的参数数量要和调用的一致
NSMethodSignature *sig =[[selfclass]instanceMethodSignatureForSelector:selector];
// NSMethodSignature *sig =[NSNumber instanceMethodSignatureForSelector:@selector(init)]
//通过签名初始化
NSInvocation *invocation =[NSInvocationinvocationWithMethodSignature:sig];
//设置target
[invocation setTarget:self];
//设置索引子
[invocation setSelector:selector];
//消息调用
[invocation invoke];
}
-(void)say{
NSLog(@"someone say");
}
最后我们会在控制台上看到打印信息了2.带参数的NSIvocaton的调用
- (void)viewDidLoad {
[superviewDidLoad];
SEL selector =@selector(say:listen:);
//创建一个函数签名这里的函数签名可以是任意的,但是需要注意 函数签名的参数数量要和调用的一致
NSMethodSignature *sig =[[selfclass]instanceMethodSignatureForSelector:selector];
//通过签名初始化
NSInvocation *invocation =[NSInvocationinvocationWithMethodSignature:sig];
//设置target
[invocation setTarget:self];
//设置索引子
[invocation setSelector:selector];
//设置参数参数在使用的时候都是取址的 如果是oc对象也是取地址
NSString *a=@"第一个参数";
NSString *b=@"第二个参数";
[invocation setArgument:&aatIndex:2];//这里的index必须2开始,因为target和selector各占了一个索引,所以上面设置tagrget、selector还有另外一种写法.如下:
// UIViewController *vc =self;
// [invocation setArgument:&vc atIndex:0];
// [invocation setArgument:&selector atIndex:1];
[invocation setArgument:&batIndex:3];
//消息调用
[invocation invoke];
}
-(void)say:(NSString *)a listen:(NSString *)b{
NSLog(@"说了:%@,听到:%@",a,b);
}
两种写法 控制台打印的信息也完全一样3.有返回值得NSIvocation的调用
- (void)viewDidLoad {
[superviewDidLoad];
SEL selector =@selector(say:listen:);
//创建一个函数签名这里的函数签名可以是任意的,但是需要注意 函数签名的参数数量要和调用的一致
NSMethodSignature *sig =[[selfclass]instanceMethodSignatureForSelector:selector];
//通过签名初始化
NSInvocation *invocation =[NSInvocationinvocationWithMethodSignature:sig];
//设置target
[invocation setTarget:self];
//设置索引子
[invocation setSelector:selector];
//设置参数参数在使用的时候都是取址的 如果是oc对象也是取地址
NSString *a=@"第一个参数";
NSString *b=@"第二个参数";
[invocation setArgument:&aatIndex:2];
[invocation setArgument:&batIndex:3];
//消息调用
[invocation invoke];
//现在是有返回类型的我们要申明一个变量来保存这个返回值
NSString *rtStr;
//对于这里的返回值我们也可以自己去设置 我们这里只是取返回值
// [invocation setReturnValue:&b];
[invocation getReturnValue:&rtStr];
//检查结果
NSLog(@"%@",rtStr);
}
-(NSString *)say:(NSString *)a listen:(NSString *)b{
return [NSStringstringWithFormat:@"说了:%@听到:%@",a,b];
}