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.

Leave a Comment