Question

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.

Was it helpful?

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).

OTHER TIPS

performSelector:withObject: will be slightly slower than calling the method directly. The indirection also means that the compiler can't do proper type checking. With ARC enabled, you'll also run into issues where the compiler will complain because it is impossible to determine exactly what the memory management policy might be.

In general, such indirection -- often called reflection but more accurately referred to as meta-programming -- is to be avoided exactly because it moves what should be compile time detectable failures to runtime failures.

Such dynamism is only needed when the name of the selector -- the name of the method -- being called cannot be determined at compile time. It should not be used for @optional methods in protocols nor should it be used during delegation (in both cases, respondsToSelector: + a direct method call are a far better pattern to employ).

The performSelector: method allows you to send messages that aren’t determined until runtime. For more info read this.

If your app wants to make use of reflection, where in by changing some values in configuration file you want to invoke a different method (Different adapters). Or based on object type you would like to invoke a different method on runtime.

If you developing a customizable product this a powerful feature.

I like to use [id performSelecter:selector withObject] when declare and implements a custom protocol,and delegate pattern, its also an use case, where we should use performselector rather then direct calling the method...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top