Search code examples
objective-ccocoacocoa-touchcocoa-design-patterns

What does the performSelector method do?


What does performSelector do? What is the difference between creating a new NSThread and the performSelector method?

How it works and where should we use it?


Solution

  • All of these perform the same task, that is make the doStuff method on anObject execute synchronously on the current thread:

    // 1
    [anObject doStuff];
    
    // 2
    [anObject performSelector:@selector(doStuff)];
    
    // 3
    objc_msgSend(anObject, @selector(doStuff));
    
    // 4
    IMP imp = [anObject methodForSelector:@selector(doStuff)];
    imp(anObject, @selector(doStuff));
    
    1. Is how you normally should go about to do stuff.
    2. Is for dynamically dispatching a message. Use if the selector is unknown, or provided by a client, for example if you implement an target-action pattern. or if the class of anObject is unknown, usually used by first asking if the object has the method with -[NSObject respondsToSelector:].
    3. Is what no 1. is actually compiled down to. Usually never any real need to do this.
    4. Cached the actual IMP (implementation) for a method, and then call it directly. Can sometimes be faster than 1. if used in a tight loop. Just remember; premature optimization is evil.

    What you need to grasp is that in Objective-C methods are more important than classes/interfaces. Usually you do not query an object if it belongs to a particular class, or conforms to any protocol, that is for the compiler to complain about. At run-time you instead query for specific methods.

    In short: It does not matter what you are, just what you can do.

    As a convenience NSObject also have several siblings to performSelector that are asynchronios. Most notably:

    • performSelector:withObject:afterDelay: - To execute the method on the current thread after a delay.
    • performSelectorInBackground:withObject: - To execute the method on a new background thread.
    • performSelectorOnMainThread:withObject:waitUntilDone: - To execute the method on the main thread.
    • performSelector:onThread:withObject:waitUntilDone: - To execute the method on any thread.

    The asynchronous performers all depend on a NSRunLoop to function. This is not something you need to worry about unless you spawn a thread yourself. If you do then you need to also run the new threads run loop. Just skip that for now.