如何将参数传递给NSTimer中调用的方法

时间:2011-03-02 10:32:35

标签: objective-c arguments nstimer nsinvocation

我有一个调用方法的计时器,但这个方法需要一个参数:

theTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(timer) userInfo:nil repeats:YES];

应该是

theTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(timer:game) userInfo:nil repeats:YES];

现在这种语法似乎不对。我试过NSInvocation但是我遇到了一些问题:

timerInvocation = [NSInvocation invocationWithMethodSignature:
        [self methodSignatureForSelector:@selector(timer:game)]];

theTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval
        invocation:timerInvocation
        repeats:YES];

我应该如何使用调用?

3 个答案:

答案 0 :(得分:11)

鉴于此定义:

- (void)timerFired:(NSTimer *)timer
{
   ...
}

然后你需要使用@selector(timerFired:)(这是方法名称,没有任何空格或参数名称,但包括冒号)。您要传递的对象(game?)是通过userInfo:部分传递的:

theTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval 
                                            target:self 
                                          selector:@selector(timerFired:) 
                                         userInfo:game
                                          repeats:YES];

在您的计时器方法中,您可以通过计时器对象的userInfo方法访问此对象:

- (void)timerFired:(NSTimer *)timer
{
    Game *game = [timer userInfo];
    ...
}

答案 1 :(得分:5)

正如@DarkDust指出的那样,NSTimer期望其目标方法具有特定的签名。如果由于某种原因你无法遵守,你可以改为使用NSInvocation,但在这种情况下,你需要使用选择器,目标和参数完全初始化它。例如:

timerInvocation = [NSInvocation invocationWithMethodSignature:
                   [self methodSignatureForSelector:@selector(methodWithArg1:and2:)]];

// configure invocation
[timerInvocation setSelector:@selector(methodWithArg1:and2:)];
[timerInvocation setTarget:self];
[timerInvocation setArgument:&arg1 atIndex:2];   // argument indexing is offset by 2 hidden args
[timerInvocation setArgument:&arg2 atIndex:3];

theTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval
                                        invocation:timerInvocation
                                           repeats:YES];

单独调用invocationWithMethodSignature并不能完成所有这些操作,它只是创建一个能够以正确方式填充的对象。

答案 2 :(得分:2)

您可以将NSDictionary与命名对象(例如myParamName => myObject)一起传递到userInfo这样的参数

theTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval 
                                            target:self 
                                          selector:@selector(timer:) 
                                          userInfo:@{@"myParamName" : myObject} 
                                           repeats:YES];

然后在timer:方法中:

- (void)timer:(NSTimer *)timer {
    id myObject = timer.userInfo[@"myParamName"];
    ...
}