Search code examples
iosobjective-ccocoaperformselector

performSelector or directly


I understand that these both are bit similar, but there must be any internal difference between two,

[anObject performSelector:@selector(thisMethod:) withObject:passedObject];

is equivalent to:

[anObject thisMethod:passedObject];

Please tell me what is the differnce in terms of compilation, memory etc.


Solution

  • The performSelector family of methods are for special cases, the vast majority of method invocations in Obj-C should be direct. Some differences:

    Indirect: When using performSelector to invoke a method you have two method invocations; that of performSelector and the target method.

    Arguments are objects: When invoking via performSelector all arguments must be passed as objects, e.g. if invoking a method which takes a double then that value must be wrapped as an NSNumber before being passed to performSelector. The performSelector methods unwraps non-object arguments before calling the target method. In direct invocation no wrapping or unwrapping is required.

    Only two arguments: The performSelector family only includes variants which pass 0, 1 or 2 arguments so you cannot use them to invoke a method which takes 3 or more arguments.

    You probably see most of the above as negatives, so what are the benefits?

    Dynamic selector: The performSelector family allow you to invoke a method which is not known until runtime, only its type need be known (so you can pass the right arguments and get the right result); in other words the selector argument may be an expression of type SEL. This might be used when you wish to pass a method as an argument to another method and invoke it. However if you are compiling with ARC using dynamic selectors is non-trivial and usually produces compiler warnings, as without knowing the selector ARC cannot know the ownership attributes of the arguments.

    Delayed execution: The performSelector family includes methods which invoke the method after a delay.

    In general use direct method invocation, only if that does not give you what you require do you need to consider the performSelector family (or its even more esoteric cousins).