前提:
在 iOS中可以直接调用某个对象的消息方式有两种:
一种是performSelector:withObject
;
再一种就是NSInvocation
。
第一种方式比较简单,能完成简单的调用。但是对于>2个的参数或者有返回值的处理,那performSelector:withObject
就显得有点有心无力了,那么在这种情况下,我们就可以使用NSInvocation
来进行这些相对复杂的操作
NSInvocation的基本使用
//简单调用 如果只是简单调用,直接用performSelector就可以了
SEL myMethod = @selector(myLog);
//创建一个函数签名,这个签名可以是任意的。但需要注意,签名的函数的参数数量要和调用的一致。
NSMethodSignature *sig = [NSNumber instanceMethodSignatureForSelector:@selector(init)];
//通过签名初始化
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
//设置target
[invocation setTarget:self];
//设置selector
[invocation setSelector:myMethod];
//消息调用
[invocation invoke];
//调用方法
- (void)myLog
{
NSLog(@"%s",__FUNCTION__);
NSLog(@"调用了方法");
}
执行方法结果如果:
NSInvocation的多参数调用
/*
多参数调用
这个才是发挥出NSInvocation的作用
*/
SEL myMethod1 = @selector(myLog1:parm:parm:);
NSMethodSignature *sig1 = [[self class] instanceMethodSignatureForSelector:myMethod1];
//通过签名初始化
NSInvocation *invocation1 = [NSInvocation invocationWithMethodSignature:sig1];
//设置target
[invocation1 setTarget:self];
[invocation1 setSelector:myMethod1];
//设置其它参数
int a = 1;
int b = 2;
int c = 3;
[invocation1 setArgument:&a atIndex:2];
[invocation1 setArgument:&b atIndex:3];
[invocation1 setArgument:&c atIndex:4];
//retain 所有参数,防止参数被释放dealloc
[invocation1 retainArguments];
//消息调用
[invocation1 invoke];
//调用方法
- (void)myLog1:(int)a parm:(int)b parm:(int)c
{
NSLog(@"%s",__FUNCTION__);
NSLog(@"a = %d b = %d c = %d",a,b,c);
}
打印结果如图:
NSInvocation的有返回值调用
/*
NSInvocation有返回值
*/
//大体和多参数调用一样。
SEL myMethod2 = @selector(myLog2:parm:parm:);
NSMethodSignature *sig2 = [[self class] instanceMethodSignatureForSelector:myMethod2];
//通过签名初始化
NSInvocation *invocation2 = [NSInvocation invocationWithMethodSignature:sig2];
//设置target
[invocation2 setTarget:self];
[invocation2 setSelector:myMethod2];
//设置其它参数
int d = 10;
int e = 11;
int f = 12;
[invocation2 setArgument:&d atIndex:2];
[invocation2 setArgument:&e atIndex:3];
[invocation2 setArgument:&f atIndex:4];
//retain 所有参数,防止参数被释放dealloc
[invocation2 retainArguments];
//消息调用
[invocation2 invoke];
/*
有返回值的时候,需要先消息调用,再去获取返回值!~
*/
//定义一个返回值
int sum;
//获取返回值
[invocation2 getReturnValue:&sum];
//打印返回值
NSLog(@"sum = %d",sum);
//调用方法
- (int)myLog2:(int)d parm:(int)e parm:(int)f
{
NSLog(@"%s",__FUNCTION__);
NSLog(@"d = %d e = %d f = %d",d,e,f);
return d+e+f;
}
打印结果如图: