I. function call Overview
Objective-C does not support multiple inheritance (same as Java and Smalltalk), while C ++ supports multiple inheritance. Objective-C is dynamic binding, and its class library is easier to operate than C ++. Objective-C allows access to methods and classes based on string names at runtime, and supports dynamic connection and addition of classes. C ++ follows the Simula 67 (an early OO language) School in object-oriented programming, while Objecive-C belongs to the Smalltalk School, and the Simula 67 school is safer, most errors can be found during compilation. In C ++, the static type of an object determines whether you can send a message to it. For Objective-C, it is determined by the dynamic type.
Compared with C ++, Objective-C emphasizes the dynamic nature of types and sacrifices some execution performance. However, due to the clear model, these sacrifices can be remedied by more advanced compilation technologies today.
Generation of Message 2
In Objective-c, messages can be bound to corresponding functions until they are run:
[reveiver message];
During processing, the compiler processes the above expression as follows:
objc_msgSend(receiver,selector);
If the method has multiple parameters, it is processed as follows:
objc_msgSend(receiver,selector,arg1,arg2,…….);
Now we know that function calls in Objective-c will be preprocessed by the compiler, And the obj_msgSend function is called to send messages. What is selector? How does a handler call a specified function and how does it implement it? The following sections describe them one by one.
Message-related structures in three types of objects
First, let's take a look at several data structures and data types related to message transmission.
1.struct objc_method_list **methodLists
In the previous section, we know that there is a struct objc_method_list ** methodLists in the Class Object objc_class, which is actually a method ing table.
The following is the structure of the objc_method_list struct objc_method_list {
struct objc_method_list *obsolete int method_count struct objc_method method_list[1]
}
Include an objc_method struct in objc_method_list
The following is the structure of the objc_method struct objc_method {SEL method_name char * method_types IMP method_imp}
Objc_method is used to represent a method. It contains a method SEL-representing the name of the method, a types-representing the parameters of the method, and an IMP-pointing to the specific implementation function pointer of the method. The parameters are described below. Shows the general situation of the function ing table.
2. SEL (An opaque type that represents a method selector)
The document defined as typedef struct objc_selector * SEL does not reveal what objc_selector is, but the @ selector command is provided to generate it:
SEL method = @ selector (viewDidLoad );
NSLog (@ "% s", (char *) method); // viewDidLoad
During the compilation of Objective-C, a unique ID is generated based on the method name to distinguish this method. This ID is of the SEL type. (A selector is the name used to select a method to execute for an object, or the unique identifier that replaces the name when the source code is compiled. A selector by itself doesn't do anything. it simply identifies a method. the only thing that makes the selector method name different from a plain string is that the compiler makes sure that selectors are unique .) as long as the method names (including parameter sequences) are the same, their IDs are the same . That is to say, no matter whether it is a super class or a subclass, no matter whether there is a relationship between a super class and a subclass, the ID is the same as long as the name is the same.
In general, SEL is a function identifier, which is generated by the compiler based on its function declaration prototype. If two different classes have the same function declaration, the same ID will be produced (Objective-c does not support function overloading in the class). How can we differentiate them? Continue reading!
3. IMP (A pointer to the function of a method implementation)
It is defined as typedef id (* IMP) (id, SEL ,...)
IMP is a function pointer pointing to the address of the first parameter instance variable of the function, that is, the address of the object that receives the message (receiver ER ), the second parameter is the method to be called by SEL, and the third is the function parameter. It is an indefinite parameter, and the return value of the function is id type. IMP is the Execution Code for the final call of a message. This method is the real implementation code. We can use this function pointer like in C.
-(Void) viewDidLoad
{
[Super viewDidLoad]; // declare a function pointer
Void (* MyPrint) (id, SEL, NSString *);
MyPrint = (void (*) (id, SEL, NSString *) [self methodForSelector: @ selector (Print :)];
MyPrint (self, @ selector (Print :), @ "Hello World ");
}
-(Void) Print :( NSString *) str
{
NSLog (@ "% @", str );
}
-(IMP) methodForSelector :( SEL) The aSelector function is used to find and locate the implementation address of the function through the IDS generated by SEL. MyPrint (self, @ selector (Print :), @ "Hello World"); call the function pointed to by the MyPrint function pointer. The parameters are handler, SEL, and parameters to be passed to the function. Through the above example, we understand that using the first parameter of the function, the handler can distinguish between different classes of functions to declare the same function.
4. Objective-c message transmission
Through the above layer-by-layer analysis and the previous section on class objects, you may understand the message transmission method in Objective-c.
First, the compiler generates a unique function ID based on the function declaration. The first member of each instance variable is isa, which points to the Class Object and stores the list of methods owned by the class object, you can find the corresponding function address through the generated function ID to call the function. If no function is found in the function ing table of the current class object, search for its parent class (super_class of each class object stores the class object address of the parent class ), if the root class is not found, a running error is reported. The process is shown in:
Successful message transmission relies on two important elements. The isa pointer in the instance is used to locate the class object to which the instance belongs, and the function to be called is found through the message ing table in the class object.
First, find the function in the message ing table by passing the selector parameter. Then, call the function and pass the instance address and parameters to the called function. Return Value.
The existence of class types gives objective-c Runtime recognition, dynamic creation, serialization, and other mechanisms.
3. The message receiver object (pointer to the Message Receiver object) and the parameters specified in the method are passed to the method to implement IMP.
4. Finally, return the return value of the method implementation as the return value of the function.
Note: The Compiler automatically inserts and calls the message function objc_msgSend. You do not need to display and call the message function in the code.
Five message transmission Summary
Here, we have understood the entire process of message transmission in Objective-c. In fact, if you are familiar with MFC, you will find that the Objective-c Runtime is very similar to the RTTI of MFC.
It is the runtime mechanism of MFC. CRuntimeClass is equivalent to Objectiv-c's object_clas class object. In CRuntimeClass, there is a pointer to the base class function. Unlike MFC, object_class is not similar to m_pNext_ClassMFC.
1. the compiler converts a message to a call to the message function objc_msgSend. This function has two main parameters: the receiver of the message and the method ID of the message, that is, SEL, the list of parameters for receiving messages at the same time.
2. objc_masSend finds the class object through isa in aggreger, and finds the method corresponding to SEL to implement IMP. Note: different classes may have different implementations for the same method, so the method implementation depends on the message receiver ).
The detailed message transmission process is as follows:
The existence of class types such as CRuntimeClass and object_class gives them runtime identification, dynamic creation, serialization, and other mechanisms.
The next section will further explore the message transmission.