NSInvocation selector 参数问题

一、概述

在 iOS中可以直接调用 某个对象的消息 方式有2种


第一种方式是使用NSObject类提供的performSelector系列方法


还有一种方式就是使用NSInvocation进行动态运行时的消息分发,动态的执行方法,相信大家一定经常使用NSObject类提供的performSelector系列方法,在这里就不再对此进行描述了,今天主要是分享一下使用NSInvocation动态执行方法。


二、NSInvocation的使用

1、执行类方法

demo代码如下:

  1. - (void)testClassMethod{  
  2.     NSString *string = nil;  
  3.       
  4.     //初始化NSMethodSignature对象  
  5.     NSMethodSignature *sig = [NSString methodSignatureForSelector:@selector(stringWithString:)];  
  6.       
  7.     //初始化NSInvocation对象  
  8.     NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];  
  9.       
  10.     //设置执行目标对象  
  11.     [invocation setTarget:[NSString class]];  
  12.       
  13.     //设置执行的selector  
  14.     [invocation setSelector:@selector(stringWithString:)];  
  15.       
  16.     //设置参数  
  17.     NSString *argString = @"test method";  
  18.     [invocation setArgument:&argString atIndex:2];  
  19.       
  20.     //执行方法  
  21.     [invocation retainArguments];  
  22.     [invocation invoke];  
  23.       
  24.     //获取返回值  
  25.     [invocation getReturnValue:&string];  
  26.       
  27.     NSLog(@"执行结果 ====%@",string);  
  28. }  


2、执行实例方法

demo示例代码如下:
  1. - (void)testInstanceMethod{  
  2.     NSString *string = [NSString stringWithFormat:@"我是一个string"];  
  3.     NSLog(@"1=%@",string);  
  4.     SEL subStringSel = @selector(substringFromIndex:);  
  5.       
  6.     //初始化NSMethodSignature对象  
  7.     NSMethodSignature *methodSignature = [[NSString class] instanceMethodSignatureForSelector:subStringSel];  
  8.       
  9.     //初始化NSInvocation对象  
  10.     NSInvocation *myInvocation = [NSInvocation invocationWithMethodSignature:methodSignature];  
  11.       
  12.     //设置target  
  13.     [myInvocation setTarget:string];  
  14.       
  15.     //设置selector  
  16.     [myInvocation setSelector:subStringSel];  
  17.       
  18.     //设置参数  
  19.     int arg1 =  2;  
  20.     [myInvocation setArgument:&arg1 atIndex:2];//参数从2开始,index 为0表示target,1为_cmd  
  21.       
  22.     //获取结果  
  23.     NSString *resultString = nil;  
  24.     [myInvocation invoke];  
  25.     [myInvocation getReturnValue:&resultString];  
  26.     NSLog(@"2=%@",resultString);  
  27. }  


转自:http://blog.csdn.net/yhawaii/article/details/8306637

//多参数解决
NSInvocationOperation 的 initWithTarget:selector:object: 里面的selector只能有0个或1个参数,参数类型必须为id,返回值可以是void,原始类型,或者id

如果要调用的方法有多个参数,可以使用如下方法:
SEL theSelector = @selector(yourMethodWithString:number:) 
NSMethodSignature * sig = [self methodSignatureForSelector:theSelector]; 
NSInvocation * theInvocation = [NSInvocation   
invocationWithMethodSignature:sig]; 
[theInvocation setTarget:self]; 
[theInvocation setSelector:theSelector]; 

NSString *firstArgument = [NSString stringWithString:@"Test"]; 
NSNumber *secondArgument = [NSNumber numberWithInt:2]; 
[theInvocation setArgument:&firstArgument atIndex:2]; 
[theInvocation setArgument:&secondArgument atIndex:3]; 
[theInvocation retainArguments];

比较麻烦是不是,不如把所有参数打开到NSArray或NSDictionary,然后使用一个参数调用
//使用字典保存参数,参照下面userInfo的例子

另外,也可以考虑使用Grand Central Dispatch,Block会自动处理参数的retain和release,多个参数没有任何问题

转自:http://www.cocoachina.com/bbs/simple/?t97816.html

//资料讨论了selector参数传值问题
资料:http://www.cocoachina.com/bbs/read.php?tid-61790.html

 iPhone: NSTimer and that thing called userInfo

Tuesday, May 12, 2009   

As I am implementing some stuff, I had reason to send along some information to a NSTimer's "onComplete" method. Every example online I've seen recently using NSTimer sets the userInfo property to nil. Not very useful for me to learn from. After a little banter on an email list, I understand how this thing works.
  1. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  
  2.  UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];  
  3.  UILabel *cellLabel = (UILabel *)[newCell.contentView viewWithTag:1];   
  4.  [newCell setSelected:YES animated:YES];  
  5.    
  6.  NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];  
  7.  [myDictionary setObject:tableView forKey:@"table"];  
  8.  [myDictionary setObject:indexPath forKey:@"indexPath"];  
  9.  // The colon after the onTimer allows for the argument  
  10.  [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(onTimer:) userInfo:myDictionary repeats:NO];  
  11.  [myDictionary release];  
  12. }  



So the onTimer method will get called after .5 seconds and it's being sent the userInfo object containing that NSMutableDictionary. Now to use that...
  1. - (void)onTimer:(NSTimer *)timer {  
  2.  NSLog(@"--- %@", [timer userInfo] );  
  3.  [[[timer userInfo] objectForKey:@"table"] deselectRowAtIndexPath:[[timer userInfo] objectForKey:@"indexPath"] animated:YES];  
  4.         // I have a reference to the tableView so I can do this below  
  5.         // but to show how the keys work, the call above these works  
  6.  //[table deselectRowAtIndexPath:[[timer userInfo] objectForKey:@"indexPath"] animated:YES];  
  7. }  


Ta da. Now I see how this works, and userInfo has a type of (id) meaning it can be anything.

果然可行
  1. [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(handleTimer:) userInfo:@"参数" repeats:YES];  
  2. 用的时候只要在下面函数里调用强制转换的userinfo就行,  
  3. -(void)handleTimer:(NSTimer*)timer  
  4. {  
  5. //这里使用(NSString *)[timer userInfo]  
  6. }  
转自:http://blog.csdn.net/ericsuper/article/details/7242312
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章