Is there any way that I can pass arguments in selector?
example: I have this method
- (void)myMethod:(NSString*)value1 setValue2:(NSString*)value2{ }
and I need to call this function through a selector passing two arguments.
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(/*my method*/) userInfo:nil repeats:YES];
How can I do this?
The action method must take one parameter, namely the sender (which in this case will be the button). If the action method needs more information at the time that it is called, you must provide that information in some other way, e.g. as an instance property that the action method can access when it is called.
Use Selectors to Arrange Calls to Objective-C Methods In Objective-C, a selector is a type that refers to the name of an Objective-C method. In Swift, Objective-C selectors are represented by the Selector structure, and you create them using the #selector expression.
In Objective-C, selector has two meanings. It can be used to refer simply to the name of a method when it's used in a source-code message to an object. It also, though, refers to the unique identifier that replaces the name when the source code is compiled. Compiled selectors are of type SEL .
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]; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With