Objective-C: Calling selectors with multiple arguments
In MyClass.m, I've defined
- (void) myTest: (NSString *) withAString{
NSLog(@"hi, %@", withAString);
}
and the appropriate declaration in MyClass.h . Later I want to call
[self performSelector:@selector(mytest:withAString:) withObject: mystring];
in MyClass.m but I get an error similar to * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[MyClass myTest:withAtring:]: unrecognized selector sent to instance 0xe421f0'
I tried a simpler case with a selector that took no arguments that printed a string to console and that worked just fine. What's wrong with the code and how can I fix it? Thanks.
Solution 1:
In Objective-C, a selector's signature consists of:
- The name of the method (in this case it would be 'myTest') (required)
- A ':' (colon) following the method name if the method has an input.
- A name and ':' for every additional input.
Selectors have no knowledge of:
- The input types
- The method's return type.
Here's a class implementation where performMethodsViaSelectors method performs the other class methods by way of selectors:
@implementation ClassForSelectors
- (void) fooNoInputs {
NSLog(@"Does nothing");
}
- (void) fooOneIput:(NSString*) first {
NSLog(@"Logs %@", first);
}
- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {
NSLog(@"Logs %@ then %@", first, second);
}
- (void) performMethodsViaSelectors {
[self performSelector:@selector(fooNoInputs)];
[self performSelector:@selector(fooOneInput:) withObject:@"first"];
[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];
}
@end
The method you want to create a selector for has a single input, so you would create a selector for it like so:
SEL myTestSelector = @selector(myTest:);
Solution 2:
Your method signature is:
- (void) myTest:(NSString *)
withAString happens to be the parameter (the name is misleading, it looks like it is part of the selector's signature).
If you call the function in this manner:
[self performSelector:@selector(myTest:) withObject:myString];
It will work.
But, as the other posters have suggested, you may want to rename the method:
- (void)myTestWithAString:(NSString*)aString;
And call:
[self performSelector:@selector(myTestWithAString:) withObject:myString];