10
votes

Can anyone enlighten me as to the differences between the two statements below.

[self playButtonSound];

AND:

[self performSelector:@selector(playButtonSound)];

I am just asking as I had some old code that used @selector, now with a little more knowledge I can't think why I did not use [self playButtonSound] instead, they both seem to do the same as written here.

gary

2
Thank you, I understand now, much appreciated. - fuzzygoat
Van: why did you delete, this is helpful is it not? They definitely will do the same thing. A small difference is that the first example will be sending one message, playButtonSound; the second will be sending two messages, first performSelector:, which will then send playButtonSound. I would always go for the first option unless you have no choice, if only for readability. - fuzzygoat

2 Answers

11
votes

Both to the same thing, but [self playButtonSound]; is definitely the normal way to invoke a method in Objective-C. However, using performSelector: allows you to call a method that is only determined at runtime.

From the NSObject Protocol Reference:

The performSelector: method is equivalent to sending an aSelector message directly to the receiver. For example, all three of the following messages do the same thing:

id myClone = [anObject copy];
id myClone = [anObject performSelector:@selector(copy)];
id myClone = [anObject performSelector:sel_getUid("copy")];

However, the performSelector: method allows you to send messages that aren’t determined until runtime. A variable selector can be passed as the argument:

SEL myMethod = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector:myMethod];
6
votes
[self playButtonSound]; 

Here compiler will check if your object responds to -playButtonSound message and will give you a warning if it does not.

[self performSelector:@selector(playButtonSound)];

Calling -playButtonSound this way you will not get compiler warning. However you can check dynamically if objects responds to a given selector - so you can safely attempt to call arbitrary selector on a object without specifying its type and not getting compiler warnings (that may be useful for example for calling optional methods in a objects delegate):

if ([self respondsToSelector:@selector(playButtonSound)])
  [self performSelector:@selector(playButtonSound)];