views:

2533

answers:

3

I'm still kind of new to Objective-C and I'm wondering what is the difference between the following two statements?

[object performSelector:@selector(doSomething)]; 

[object doSomething];
+26  A: 

Basically performSelector allows you to dynamically determine which selector to call a selector on the given object. In other words the selector need not be determined before runtime.

Thus even though these are equivalent:

[anObject aMethod]; 
[anObject performSelector:@selector(aMethod)];

The second form allows you to do this:

SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector: aSelector];

before you send the message.

ennuikiller
+1 Nice explanation.
Quinn Taylor
It's worth pointing out that you would actually assign the result of findTheAppropriateSelectorForTheCurrentSituation() to aSelector, then invoke [anObject performSelector:aSelector]. @selector produces a SEL.
Daniel Yankowsky
I edited it to complete the example, renaming the variable for clarity.
bbum
Using `performSelector:` is something you probably only do if you implement target-action in your class. The siblings `performSelectorInBackground:withObject:` and `performSelectorOnMainThread:withObject:waitUntilDone:` are often more useful. For spawning a background thread, and for calling back results to the main thread from said background thread.
PeyloW
+1  A: 

@ennuikiller is spot on. Basically, dynamically-generated selectors are useful for when you don't (and usually can't possibly) know the name of the method you'll be calling when you compile the code.

One key difference is that -performSelector: and friends (including the multi-threaded and delayed variants) are somewhat limited in that they are designed for use with methods with 0-2 parameters. For example, calling -outlineView:toolTipForCell:rect:tableColumn:item:mouseLocation: with 6 parameters and returning the NSString is pretty unwieldy, and not supported by the provided methods.

Quinn Taylor
To do that, you'd need to use an `NSInvocation` object.
Dave DeLong
Another difference: `performSelector:` and friends all take object arguments, meaning you can't use them to call (for example) `setAlphaValue:`, because its argument is a float.
Chuck
Both are excellent points.
Quinn Taylor
+1  A: 

Selectors are a bit like function pointers in other languages. You use them when you don't know at compile time which method you want to call at runtime. Also, like function pointers, they only encapsulate the verb part of invocation. If the method has parameters, you will need to pass them as well.

An NSInvocation serves a similar purpose, except that it binds together more information. Not only does it include the verb part, it also includes the target object and the parameters. This is useful when you want to call a method on a particular object with particular parameters, not now but in the future. You can build an appropriate NSInvocation and fire it later.

Daniel Yankowsky
Selectors really aren't at all like a function pointer in that a function pointer is something you can call with arguments and a selector can be used to call a particular method on any object that implements it; a selector does not have the full context of invocation like a function pointer.
bbum
Selectors aren't the same as function pointers, but I still think they are similar. They represent verbs. C function pointers also represent verbs. Neither is useful without additional context. Selectors require an object and parameters; function pointers require parameters (which might include an object upon which to operate). My point was to highlight how they are different from NSInvocation objects, which do contain all the necessary context. Perhaps my comparison was confusing, in which case I apologize.
Daniel Yankowsky