1

Possible Duplicate:
Using -performSelector: vs. just calling the method

I can accomplish the same task in my application by doing:

[self performSelector:@selector(displayOneLife)];

and:

[self displayOneLife];

Is it better to use one or the other depending on the situation? If so, can someone elaborate for me? I would just like to use Objective-C best practices.

Thank you, Joey

Community
  • 1
  • 1
Joey
  • 1,144
  • 3
  • 15
  • 29

4 Answers4

3

The -performSelector approach is usually used when you would like to invoke some selector not known at compilation time. For instance, UIButton uses it to invoke the action you wire it up to when a user hits it (the button knows the name of the method it is hooked up in IB and the class it it hooked up to).

For all other cases you should go with the latter as you don't want to convert your code into an unreadable puzzle.

P.S. -performSelector + dynamic selector name construction can be used to work around Apple's static analyzer which seeks the binary for prohibited invocations :)

Anton
  • 2,483
  • 2
  • 23
  • 35
  • P.S. don't do that. Calling non-public API both leaves you at risk of rejection and will quite likely be a source of crashes and/or maintenance issues in the future. – bbum Nov 09 '12 at 19:08
  • :-D btw any specific reason apart from "do-not-use-private-api-as-it-might-break-when-a-new-version-comes-out"? – Anton Nov 09 '12 at 19:09
  • I'm asking as there are cases you cannot solve without using private api, not to mention your own methods' invocations named the same as private api would lead to rejection. – Anton Nov 09 '12 at 19:11
  • First off, use of private API, regardless of how you do it, is a violation of the app store terms of service and will get your app axed, if discovered. Secondly, private API is private for a reason; it often has fragility, dependencies, and behaviors that will behave in an undefined fashion when used incorrectly. – bbum Nov 09 '12 at 23:35
2

@selector has a very specific use, and you should not use it to call known methods.

You use @selector to inform other classes of one of your methods that should be called.

For example you can pass the class countNumber a selector to your method @selector(result:) so that the other class will call your method when it has completed its task.

example code:

- (void)calculateANumber
{
    [NumbersClass countNumber:myNumber withResult:@selector(result:)];
}

//This method will get called by NumbersClass, even tho it didnt know its existence before
- (void)result:(int)countResult
{
    myResult = countResult;
}

Just an example, obviously, it does nothing

pedros
  • 1,197
  • 10
  • 18
2

You can store a selector in a variable, so performSelector: is useful for when you don't know at compile-time what message you want to send. For example, the target-action system is based on selectors. Here's a rudimentary implementation of a control:

@interface FakeControl : NSObject

@property(nonatomic, strong) id target;
@property(nonatomic, assign) SEL action;

- (void)click;

@end

@implementation FakeControl

- (void)click {
    [target performSelector:action];
}

@end

By using a selector, we can have the control send any message we want at runtime when it's clicked.

Chuck
  • 234,037
  • 30
  • 302
  • 389
0

If you have to do some thing inline especially on the same thread

[self displayOneLife] 

is good enough

But there are many instances, where you want to do the execution on another thread, or after a delay etc. If you just type, [self perform ...], you will see so many suggestions for methods available for performSelector, each of the method signatures will help you understand what it does.

Select one of the methods and just command click on the method name. It will show you details about what the method does etc.

It is a very good question but has many answers. Runloops, threads, delays, asynchronous operations are all reasons.

Srikanth
  • 1,725
  • 2
  • 10
  • 11