@selector中的参数
有什么办法可以在select器中传递参数吗?
例如:我有这个方法
- (void)myMethod:(NSString*)value1 setValue2:(NSString*)value2{ }
我需要通过传递两个参数的select器来调用这个函数。
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(/*my method*/) userInfo:nil repeats:YES];
我该怎么做?
你可以使用NSTimer
方法:
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds invocation:(NSInvocation *)invocation repeats:(BOOL)repeats;
相反,因为一个NSInvocation
对象将允许你传递参数; NSInvocation
对象,正如文档定义的那样:
一个Objective-C消息呈现为静态的,也就是说,一个动作变成了一个对象。
使用select器创buildNSTimer
对象时,需要的方法是:
- (void)timerFireMethod:(NSTimer*)theTimer
NSInvocation
允许你设置目标,select器和你传入的参数:
SEL selector = @selector(myMethod:setValue2:); NSMethodSignature *signature = [MyObject instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setSelector:selector]; NSString *str1 = @"someString"; NSString *str2 = @"someOtherString"; //The invocation object must retain its arguments [str1 retain]; [str2 retain]; //Set the arguments [invocation setTarget:targetInstance]; [invocation setArgument:&str1 atIndex:2]; [invocation setArgument:&str2 atIndex:3]; [NSTimer scheduledTimerWithTimeInterval:0.1 invocation:invocation repeats:YES];
其中MyObject
是myMethod:setValue2:
被声明并实现的类 – instanceMethodSignatureForSelector:
是一个在NSObject
上声明的便利函数,它为您返回一个NSMethodSignature
对象,并将其传递给NSInvocation
。
此外,要注意,使用setArgument:atIndex:
,要传递给设置为select器的方法的参数的索引将从索引2开始。从文档:
索引0和1分别表示隐藏的参数self和_cmd; 你应该直接用setTarget:和setSelector:方法设置这些值。 通常在消息中传递的参数使用索引2和更大。
对于scheduledTimerWithTimeInterval:
:,您传递的select器只能有一个参数。 此外,它的一个参数必须是NSTimer *
对象。 换句话说,select器必须采取以下forms:
- (void)timerFireMethod:(NSTimer*)theTimer
你可以做的是将参数存储在userInfo
字典中,并从定时器callback中调用你想要的select器:
- (void)startMyTimer { /* ... Some stuff ... */ [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(callMyMethod:) userInfo:[NSDictionary dictionaryWithObjectsAndKeys:someValue, @"value1", someOtherValue, @"value2", nil] repeats:YES]; } - (void)callMyMethod:(NSTimer *)theTimer { NSString *value1 = [[theTimer userInfo] objectForKey:@"value1"]; NSString *value2 = [[theTimer userInfo] objectForKey:@"value2"]; [self myMethod:value1 setValue2:value2]; }
看起来像块(假设这是针对雪豹)的工作。
-jcr
块现在看起来像是一个明显的答案…但在传统的运行时中,还有一个非常普遍的习惯用法,就是在单个对象中挑选你的参数:
- (void)doMyMethod:(NSDictionary *)userInfo { [self myMethod: [userInfo objectForKey:@"value1"] setValue2: [userInfo objectForKey:@"value2"]]; } - (void)myMethod:(NSString*)value1 setValue2:(NSString*)value2{ }
现在你可以派遣到
[self performSelector:@selector(doMyMethod:) withObject:@{@"value1":@"value1",@"value2":@"value2"}];
@selector(myMethod:setValue2:)
由于您的方法的select器不只是所谓的myMethod
,而是myMethod:setValue2:
另外(我可以在这里基地),我相信技术上你可以删除冒号之间的话,因此也使用@select器@selector(myMethod::)
但除非别人可以证实,否则不要引用我。