views:

181

answers:

3

Hi all,

I'm having a problem with performSelector. It works if I call a method without parameters, but it doesn't even call the method if I pass a parameter.

Example:

- (void)test
{
 NSLog(@"test"); //it works!!
}    
...
[self performSelector:@selector(test) withObject:nil afterDelay:1.0];


- (void)switchOn:(NSNumber *) index
{
 NSLog(@"switchOn"); //it doesn't work :-(
}   
....
NSLog(@"int is %d", [((NSNumber *)obj) intValue]); //print the correct value
[self performSelector:@selector(switchOn:) withObject:obj afterDelay:1.0];

I get no errors neither. Where could it be the problem?

thanks

+1  A: 

What is the type of the parameter for the switchOn: selector?

It must be of type id otherwise performSelector:WithObject: won't work. To quote the docs:

aSelector should identify a method that takes a single argument of type id. For methods with other argument types and return values, use NSInvocation.

ivans
+1  A: 

performSelectorWithObject: sends a message to the selector with the object you supplied as the first argument. The receiving method must accept a single parameter of type id. For anything else use NSInvocation.

You might want to check out a similar question about this.

Denis 'Alpheus' Čahuk
A: 

Try to use:

- (void)switchOn:(id)index
Michael Kessler
-1 because this is probably the worst possible way to phrase the answer that I can imagine. He should not be forced to redefine his interface if he wants to dynamically call a selector - what he does want is a way to call any arbitrary selector.
ivans
@ivans: I might be wrong, but don't you basically say the same thing without code? The method must take a parameter with type `id`. What other way is there besides changing the method signature?
Felix Kling
He's asking "how do I invoke this thing that I have already written?" I'm sure he doesn't want to know about changing his code, or he would have adapted it to be called without parameters. Hence, I assumed that he wanted someone to tell him that NSInvocation exists.
ivans
I hope you understand your own answer... "aSelector should identify a method that takes a single argument of type id" - don't you see any similarity? Please undo your "-1" - I don't see any good reason for that.
Michael Kessler
@ivans: Oh I see... Maybe you should make this more clear in your answer. Anyway, this answer is not wrong.
Felix Kling
@Michael, read my entire answer. I'm offering a clear alternative dynamic call option when the parameter is not of type id (or cannot be made to be an id). Suggesting that you can just change method signatures demonstrates that you are solving problems symptomatically.
ivans
@ivans, the question was why 'performSelector' doesn't call the method. I have provided an answer. You have also added an alternative - good for you, but it wasn't the question. If the only use of this method is by 'performSelector' then I see nothing wrong with my answer. Why haven't you also mentioned that there is a possibility to use NSTimer and call the 'switchOn' from the method that was invoked by the timer? I believe that there are many ways to solve every problem, my solution was good enough to answer the current question. One can't know/write all the existing solutions.
Michael Kessler
..I saw the question, suggested a correct solution and don't see any reason for reducing my reputation only because there is another possible solution that wasn't even asked.
Michael Kessler
+1 to make this end.
Felix Kling
Thank you, @Felix.
Michael Kessler