1

I've been having problems getting an NSTimer to fire, and I assumed it had to with multi-threading issues. Just to be sure I was creating the timer correctly, I created the following test code and I placed it into my main view controller's initWithNibName. Much to my surprise, it also failed to fire there.

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(timerTest:paramTwo:paramThree:)]];
NSString *a = @"a";
NSString *b = @"b";
NSString *c = @"c";
[invocation setArgument:&a atIndex:2]; //indices 0 and 1 are target and selector respectively, so params start with 2
[invocation setArgument:&b atIndex:3];
[invocation setArgument:&c atIndex:4];
[[NSRunLoop mainRunLoop] addTimer:[NSTimer timerWithTimeInterval:5 invocation:invocation repeats:NO] forMode:NSDefaultRunLoopMode];

Any clues as to what is wrong with this code? It seems to do exactly what the documentation specifies for using an NSInvocation with an NSTimer.

CodaFi
  • 43,043
  • 8
  • 107
  • 153
Regan
  • 1,487
  • 2
  • 28
  • 43

1 Answers1

3

NSInvocations also have to have a target and a selector in addition to a method signature and arguments:

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(timerTest:paramTwo:paramThree:)]];
NSString *a = @"a";
NSString *b = @"b";
NSString *c = @"c";
[invocation setArgument:&a atIndex:2]; //indices 0 and 1 are target and selector respectively, so params start with 2
[invocation setArgument:&b atIndex:3];
[invocation setArgument:&c atIndex:4];
[invocation setTarget:self];
[invocation setSelector:@selector(timerTest:paramTwo:paramThree:)];
[[NSRunLoop mainRunLoop] addTimer:[NSTimer timerWithTimeInterval:1 invocation:invocation repeats:NO] forMode:NSDefaultRunLoopMode];
CodaFi
  • 43,043
  • 8
  • 107
  • 153
  • I was under the impression that the method signature contained the target and selector information; if not, what is its purpose? – Regan Jul 30 '13 at 20:10
  • 1
    Nope. Method signatures are just a string describing the format of the selector and a little bit of useless information as to the stack alignment of the arguments. NSInvocation needs it in order to make the message forwarding mechanism work in case the invocation on the original target fails. – CodaFi Jul 30 '13 at 20:11