Как передать аргумент методу, вызываемому в NSTimer - PullRequest
6 голосов
/ 02 марта 2011

У меня есть таймер, вызывающий метод, но этот метод принимает один параметр:

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

Как мне использовать Invocation?

Ответы [ 3 ]

11 голосов
/ 02 марта 2011

Учитывая это определение:

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

Затем необходимо использовать @selector(timerFired:) (это имя метода без пробелов или имен аргументов, но с двоеточиями).Объект, который вы хотите передать (game?), Передается через userInfo: part:

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

В вашем методе timer вы можете получить доступ к этому объекту через метод userInfo объекта timer:

- (void)timerFired:(NSTimer *)timer
{
    Game *game = [timer userInfo];
    ...
}
5 голосов
/ 02 марта 2011

Как указывает @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 голосов
/ 02 марта 2011

Вы можете передать 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"];
    ...
}
...