@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]; 

其中MyObjectmyMethod: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::)但除非别人可以证实,否则不要引用我。