he objc_msgSend Function
In Objective-C, messages aren’t bound to method implementations until runtime. The compiler converts a message expression,
|
into a call on a messaging function,
objc_msgSend
. This function takes the receiver and the name of the method mentioned in the message—that is, the method selector—as its two principal parameters:
|
Any arguments passed in the message are also handed to
objc_msgSend
:
|
The messaging function does everything necessary for dynamic binding:
- It first finds the procedure (method implementation) that the selector refers to. Since the same method can be implemented differently by separate classes, the precise procedure that it finds depends on the class of the receiver.
- It then calls the procedure, passing it the receiving object (a pointer to its data), along with any arguments that were specified for the method.
- Finally, it passes on the return value of the procedure as its own return value.
Note: The compiler generates calls to the messaging function. You should never call it directly in the code you write.
The key to messaging lies in the structures that the compiler builds for each class and object. Every class structure includes these two essential elements:
- A pointer to the superclass.
- A class dispatch table. This table has entries that associate method selectors with the class-specific addresses of the methods they identify. The selector for the
method is associated with the address of (the procedure that implements)setOrigin::
, the selector for thesetOrigin::
method is associated withdisplay
’s address, and so on.display
When a new object is created, memory for it is allocated, and its instance variables are initialized. First among the object’s variables is a pointer to its class structure. This pointer, called
isa
, gives the object access to its class and, through the class, to all the classes it inherits from.
Note: While not strictly a part of the language, the
isa
pointer is required for an object to work with the Objective-C runtime system. An object needs to be “equivalent” to a
struct objc_object
(defined in
objc/objc.h
) in whatever fields the structure defines. However, you rarely, if ever, need to create your own root object, and objects that inherit from
NSObject
or
NSProxy
automatically have the
isa
variable.
These elements of class and object structure are illustrated in Figure 3-1.
Figure 3-1 Messaging Framework
When a message is sent to an object, the messaging function follows the object’s
isa
pointer to the class structure where it looks up the method selector in the dispatch table. If it can’t find the selector there,
objc_msgSend
follows the pointer to the superclass and tries to find the selector in its dispatch table. Successive failures cause
objc_msgSend
to climb the class hierarchy until it reaches the
NSObject
class. Once it locates the selector, the function calls the method entered in the table and passes it the receiving object’s data structure.
------------------越是喧嚣的世界,越需要宁静的思考------------------
合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。
积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里;不积小流,无以成江海。骐骥一跃,不能十步;驽马十驾,功在不舍。锲而舍之,朽木不折;锲而不舍,金石可镂。蚓无爪牙之利,筋骨之强,上食埃土,下饮黄泉,用心一也。蟹六跪而二螯,非蛇鳝之穴无可寄托者,用心躁也。