Sunday, November 24, 2013

Messaging in Objective C

In Objective C we know that objects send messages. If you do not know about it you can refer to the one of the previous blogs Object Model of Objective C

Now the messages are not bound to the method implementation until runtime. So how does this binding happens at runtime? There is no magic here is the messaging function which does this at runtime "objc_msgSend". This function takes the receiver and the name of the method - this is the method selector name as argument,


So when we write a code like  [Object myFoo] than the compiler converts this into 

objc_msgSend(Object, myFoo) and if there are any arguments available than 

objc_msgSend(Object, myFoo, arg1, arg2,.........)

The messaging function does


  • It first find the procedure that the selector refers to.
  • Than if call the procedure passing it the receiving object and the arguments specified in the message.
  • It return the returned value as its own return value.


How?

So how if happen? How does the objc_msgSend finds the procedure? So the key lies in the structures that compiler builds for each class and its objects.

Each structure have two essential parts:
  1. A pointer to its SuperClass.
  2. Dispatch Table: This table have entries that binds the method selectors with the class-specific addresses of the methods. 
When we create a new object memory for it is allocated and its Instance variables are initialized. First among the instance variables is a pointer to its Class Structure. This pointer, is called isa, gives access to the class structure and all the classes it inherits from.

I think now things are getting clear how the selector is getting resolved. If not lets elaborate it more. 

So when a message is sent to an Object, Messaging Function follow's the object's isa pointer and find the class structure, where it looks for the selector and of cannot find it in the dispatch table it will more up to the superclass and so on... This way method implementation are looked up at runtime or we can say are dynamically bind to the method implementation.

As we see that Message Function scan through the set of classes to find the method implementation. So is this process happen every time message is sent to the Object?

Caching

yes until the message sent has not sent previously, to speed up the process the runtime system caches the selector and the method address as they are used. There is a separate cache for each class structure where it cache the class selectors and any inherited selectors. 

Bypassing the Messaging

So now what if I want to bypass all this processing. I think of it is a overhead. So how do I call the method directly?

We can get the address of the method and call it. This can be useful in very rare occasion where a particular method is being used frequently in succession. 

So to get the address of the method there is method available in the NSObject class methodForSelector:, which can be used to get the pointer to the procedure for the selector. The Pointer returned by methodForSelector should be typed cast to proper function type.

This is be used in cases where method is being used inside a for loop which runs for may be 1000 time. Than calling the function directly could save lot of processing.

Also methodForSelector: is not part of Objective C programming, it is provided by COCOA. 

I hope this will help clear up the concepts before we can start doing some coding examples with Selectors....


Happy Coding!!!

No comments:

Post a Comment