Tuesday, May 28, 2013

Few words about selector (SEL)


Introducing @selector



You are probably familiar to @selector or you should be, if you are interested in Objective-C programming. This blog entry is to describe it and make it clear how it works.


Selector is part of Cocoa framework and is widely used in many parts of system. (Ex. as part of Target-Action functionality or for Notification purposes). You can think of selector as about variable whitch holds method identificator. So why to use it? It allows us to define call to a method on object before we will knew what object it will be.

.

Selector have own type which is SEL. Lets have and example:


SEL aSelectorToAMethod = @selector(methodName);


@selector is compiler tag to interpret selector correctly. During a compilation time there is no validation on method if it exists, as selector from itself do not define on what type of object it will be used. Only its uniqueness is verified, but not even always as we can define selector on runtime (example 2):


SEL aSelectorToAMethod = NSSelectorFromString(@"methodName");

.

This way you can pass a method identifier as a variable.


How we use it? We can run it on any Objective-C Object via performSelector method. So simply as it can be - we have a method to run a method (from method variable - selector).


[object performSelector:aSelectorToAMethod ];

“performSelector”  can be called on any object, because it is defined in NSObject already - so we have this functionality out-of-the-box in every our class.


Flexibility od @selector call



“performSelector” have important overloads that can be very handy for development. 
You need to know that you can pass a value to a selector. As if one variable it is straight forward - we have overload performSelector:withObject: with two variables it can be done but with more there is a problem.
Solution is to pass all variables as array in first parameter.

SEL aSelectorToAMethod = @selector(methodName:);
NSArray *arr = [NSArray arrayWithObjects:@”one”, @“two”, nil];
[object performSelector:aSelectorToAMethod withObject:arr afterDelay:nil];

So we have array of arguments passed to a selector. There is one more thing - “afterDelay:. This is very strong advantage, that we can use to delay call for specified amount of time.
How it works? The "selected" method will run after declared time interval. Is it not beautifull?

There are more options - we can even attach a selector to thread we want or run it in a background. It is a perfect wy to initialize some communication with external service etc.

There is wide pallete of selector oriented methods described in NSObject definition you can find very useful.

Disadvantages of @selector


One of obvious things about selector is that we have to write more code for calling method and it become less readable and intuitive. As a result cod can become harder to maintain.

[object methodName];

[object performSelector:@selector(methodName)];


Second thing is that  until selector will be used in runtime we don’t know if it works. It can cause a runtime error instead of compilation error (with normal method call) and as a result it can be harder to debug and fix.

Responding to selector

There is also respondsToSelector: method. It verifies (YES/NO) if object have implemented given selector. It can help us processing different objects in different way or to run selector only on objects that have implemented given method.  

No comments:

Post a Comment