ios NSInvocation简单使用

在ios直接调用某个对象的消息是方法有两种:

一:performselector:withObject:

二:invocation

 

第一种方式比较简单,能完成简单的调用。但是对于>2个的参数或者有返回值的处理,那就需要做些额外工作才能搞定。那么在这种情况下,我们就可以使用NSInvocation来进行这些相对复杂的操作

 

NSInvocation可以处理参数、返回值。会java的人都知道凡是操作,其实NSInvocation就相当于反射操作。

 

 

 

//方法签名类,需要被调用消息所属的类AsynInvoke ,被调用的消息invokeMethod:
NSMethodSignature *sig= [[AsynInvoke class] instanceMethodSignatureForSelector:@selector(invokeMethod:)];
//根据方法签名创建一个NSInvocation
NSInvocation *invocation=[NSInvocation invocationWithMethodSignature:sig];
//设置调用者也就是AsynInvoked的实例对象,在这里我用self替代
[invocation setTarget:self];
//设置被调用的消息
[invocation setSelector:@selector(invokeMethod:)];
//如果此消息有参数需要传入,那么就需要按照如下方法进行参数设置,需要注意的是,atIndex的下标必须从2开始。原因为:0 1 两个参数已经被target 和selector占用
NSInteger num=10;
[invocation setArgument:&num atIndex:2];
//retain 所有参数,防止参数被释放dealloc
[invocation retainArguments];
//消息调用
[invocation invoke];
//如果调用的消息有返回值,那么可进行以下处理



//获得返回值类型
const char *returnType = sig.methodReturnType;
//声明返回值变量
id returnValue;
//如果没有返回值,也就是消息声明为void,那么returnValue=nil
if( !strcmp(returnType, @encode(void)) ){
	returnValue =  nil;
}
//如果返回值为对象,那么为变量赋值
else if( !strcmp(returnType, @encode(id)) ){
	[invocation getReturnValue:&returnValue];
}
else{
//如果返回值为普通类型NSInteger  BOOL

	//返回值长度
	NSUInteger length = [sig methodReturnLength];
	//根据长度申请内存
	void *buffer = (void *)malloc(length);
	//为变量赋值
	[invocation getReturnValue:buffer];

//以下代码为参考:具体地址我忘记了,等我找到后补上,(很对不起原作者)
if( !strcmp(returnType, @encode(BOOL)) ) {
	returnValue = [NSNumber numberWithBool:*((BOOL*)buffer)];
}
else if( !strcmp(returnType, @encode(NSInteger)) ){
	returnValue = [NSNumber numberWithInteger:*((NSInteger*)buffer)];
}
	returnValue = [NSValue valueWithBytes:buffer objCType:returnType];
}

 

 

调用步骤:

- (NSString *) myMethod:(NSString *)param1 withParam2:(NSNumber *)param2{
	
	NSString *result = @"Objective-C";
	NSLog(@"Param 1 = %@", param1);
	NSLog(@"Param 2 = %@", param2);
	return(result);
}

- (void) invokeMyMethodDynamically {
	SEL selector = @selector(myMethod:withParam2:);
	
	NSMethodSignature *methodSignature = [[self class] instanceMethodSignatureForSelector:selector];
	
	NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
	
	[invocation setTarget:self];
	
	[invocation setSelector:selector];

	NSString *returnValue = nil;
	NSString *argument1 = @"First Parameter";
	NSNumber *argument2 = [NSNumber numberWithInt:102];
	
	[invocation setArgument:&argument1 atIndex:2];
	[invocation setArgument:&argument2 atIndex:3];
	[invocation retainArguments];
	[invocation invoke];
	[invocation getReturnValue:&returnValue];
	
	NSLog(@"Return Value = %@", returnValue);
}

 


 

 

To do this, you need to follow these steps:
1. Form a SEL value using the name of the method and its parameter names (as
explained in Recipe 1.7).
2. Form a method signature of type NSMethodSignature out of your SEL value.
3. Form an invocation of type NSInvocation out of your method signature.
4. Tell the invocation what object you are targeting.
5. Tell the invocation what selector in that object you want to invoke.
6. Assign any arguments, one by one, to the invocation.
7. Invoke the method using the invocation object and demand a return value (if any).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值