Arguments in @selector
You could use the NSTimer
method:
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds
invocation:(NSInvocation *)invocation
repeats:(BOOL)repeats;
Instead, since an NSInvocation
object will allow you to pass arguments; an NSInvocation
object is, as the docs define it:
an Objective-C message rendered static, that is, it is an action turned into an object.
Whilst creating an NSTimer
object using a selector requires the format of the method being:
- (void)timerFireMethod:(NSTimer*)theTimer
An NSInvocation
allows you to set the target, the selector, and the arguments that you pass in:
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];
Where MyObject
is the class that myMethod:setValue2:
is declared and implemented on – instanceMethodSignatureForSelector:
is a convenience function declared on NSObject
which returns an NSMethodSignature
object for you, to be passed to NSInvocation
.
Also, to note, with setArgument:atIndex:
, the indices for arguments to be passed to the method set as the selector start at index 2. From the docs:
Indices 0 and 1 indicate the hidden arguments self and _cmd, respectively; you should set these values directly with the setTarget: and setSelector: methods. Use indices 2 and greater for the arguments normally passed in a message.
For scheduledTimerWithTimeInterval:
, the selector you pass can only have one argument. Further, its one argument must be an NSTimer *
object. In other words, the selector must take the following form:
- (void)timerFireMethod:(NSTimer*)theTimer
What you could do is store the arguments in the userInfo
dictionary and call the selector you want from the timer callback:
- (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];
}
Looks like a job for blocks (assuming this is targeted for Snow Leopard.)
-jcr