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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章