一、概述
在 iOS中可以直接调用 某个对象的消息 方式有2种
还有一种方式就是使用NSInvocation进行动态运行时的消息分发,动态的执行方法,相信大家一定经常使用NSObject类提供的performSelector系列方法,在这里就不再对此进行描述了,今天主要是分享一下使用NSInvocation动态执行方法。
二、NSInvocation的使用
1、执行类方法
demo代码如下:
- - (void)testClassMethod{
- NSString *string = nil;
- //初始化NSMethodSignature对象
- NSMethodSignature *sig = [NSString methodSignatureForSelector:@selector(stringWithString:)];
- //初始化NSInvocation对象
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
- //设置执行目标对象
- [invocation setTarget:[NSString class]];
- //设置执行的selector
- [invocation setSelector:@selector(stringWithString:)];
- //设置参数
- NSString *argString = @"test method";
- [invocation setArgument:&argString atIndex:2];
- //执行方法
- [invocation retainArguments];
- [invocation invoke];
- //获取返回值
- [invocation getReturnValue:&string];
- NSLog(@"执行结果 ====%@",string);
- }
2、执行实例方法
demo示例代码如下:
- - (void)testInstanceMethod{
- NSString *string = [NSString stringWithFormat:@"我是一个string"];
- NSLog(@"1=%@",string);
- SEL subStringSel = @selector(substringFromIndex:);
- //初始化NSMethodSignature对象
- NSMethodSignature *methodSignature = [[NSString class] instanceMethodSignatureForSelector:subStringSel];
- //初始化NSInvocation对象
- NSInvocation *myInvocation = [NSInvocation invocationWithMethodSignature:methodSignature];
- //设置target
- [myInvocation setTarget:string];
- //设置selector
- [myInvocation setSelector:subStringSel];
- //设置参数
- int arg1 = 2;
- [myInvocation setArgument:&arg1 atIndex:2];//参数从2开始,index 为0表示target,1为_cmd
- //获取结果
- NSString *resultString = nil;
- [myInvocation invoke];
- [myInvocation getReturnValue:&resultString];
- NSLog(@"2=%@",resultString);
- }
转自: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,然后使用一个参数调用
如果要调用的方法有多个参数,可以使用如下方法:
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,多个参数没有任何问题
另外,也可以考虑使用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.
- - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
- UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
- UILabel *cellLabel = (UILabel *)[newCell.contentView viewWithTag:1];
- [newCell setSelected:YES animated:YES];
- NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];
- [myDictionary setObject:tableView forKey:@"table"];
- [myDictionary setObject:indexPath forKey:@"indexPath"];
- // The colon after the onTimer allows for the argument
- [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(onTimer:) userInfo:myDictionary repeats:NO];
- [myDictionary release];
- }
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...
- - (void)onTimer:(NSTimer *)timer {
- NSLog(@"--- %@", [timer userInfo] );
- [[[timer userInfo] objectForKey:@"table"] deselectRowAtIndexPath:[[timer userInfo] objectForKey:@"indexPath"] animated:YES];
- // I have a reference to the tableView so I can do this below
- // but to show how the keys work, the call above these works
- //[table deselectRowAtIndexPath:[[timer userInfo] objectForKey:@"indexPath"] animated:YES];
- }
Ta da. Now I see how this works, and userInfo has a type of (id) meaning it can be anything.
果然可行
转自:http://blog.csdn.net/ericsuper/article/details/7242312
- [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(handleTimer:) userInfo:@"参数" repeats:YES];
- 用的时候只要在下面函数里调用强制转换的userinfo就行,
- -(void)handleTimer:(NSTimer*)timer
- {
- //这里使用(NSString *)[timer userInfo]
- }