in objective-C, the real implementation of message and method is bound in the execution phase, rather than the compilation phase. The compiler converts the message to the call of the objc_msgsend method.
the objc_msgsend method contains two required parameters: the aggreger and selector, for example,
[Receiver message]; is converted to: objc_msgsend (receiver er, selector );
the objc_msgsend method can also hold the Message Parameter, for example,
objc_msgsend (receiver er, selector, arg1, arg2 ,...);
The objc_msgsend method performs the following operations in sequence to complete dynamic binding:
1. FindProgram(Real implementation of methods ). Because different classes have different implementations for the same method, the true search for methods depends on the handler class.
2. Call this implementation and pass a series of parameters
3. Use the return value of this implementation as its own return value.
The key to message transmission is the data structure used by the compiler to build each class and object. Each class contains the following two elements:
-A pointer to the parent class.
-A scheduling table ). This scheduling table associates the selector of the class with the actual memory address of the method.
Each object has a pointer to its class.Isa. With this pointer, the object can find the class to which it belongs, and all its parent classes are found, as shown in:
When a message is sent to an object, the objc_msgsend MethodIsaThe pointer finds the class of the object and finds the selector in the scheduling table of the class. If the selector cannot be found, objc_msgsend finds the parent class by pointing to the parent class pointer, finds the selector in the scheduling table of the parent class (dispatch table), and so onNsobjectClass. Once selector is found, the objc_msgsend method calls this implementation based on the memory address of the scheduling table.
In this way, the real implementation of message and method is bound only in the execution phase.
to ensure message sending and execution efficiency, the system caches all selector and the memory address of the used method. Each class has an independent cache. The cache contains the selector of the current class and the selector inherited from the parent class. Before querying a scheduling table, the message sending system first checks the cache of the receiver object.
in case of cache hit, messaging is a little slower than function call.