Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”
Nature of method
The essence of this method is to send an objc_msgSend message. The parameters of objc_msgSend are
- Message receiver
- Message body (SEL + argument)
We can verify this by writing the following code in the main function:
LGPerson *person = [LGPerson alloc];
[person sayNB];
[person say:@"NB"];
Copy the code
Generate the CPP file, and you can see the underlying code as
LGPerson *person = ((LGPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("LGPerson"), sel_registerName("alloc"));
((void (*)(id, SEL))(void *)objc_msgSend)((id)person, sel_registerName("sayNB"));
((void (*)(id, SEL, NSString *))(void *)objc_msgSend)((id)person, sel_registerName("say:"), (NSString *)&__NSConstantStringImpl__var_folders_jl_d06jlfkj2ws74_5g45kms07m0000gn_T_main_d8842a_mi_3);
Copy the code
- Sel_registerName is the underlying implementation of @selector()
- If there is no method in the subclass, it will look up the parent class and call it
objc_msgSendSuper
To send a message to the parent class
The main process of sending messages is as follows:
- Quick find:
objc_msgSend
To find thecache_t
The cache information - Slow lookup: Recursively look up methods by itself and its parent
lookUpImpOrForward
- Unable to find message, dynamic method parsing:
resolveInstanceMethod
- Quick message forwarding:
forwardingTargetForSeletor
- Message slow forwarding: message signature
methodSignatureForSelector
And distributeforwardInvocation
- Finally, it still found the message: program crash, reported the classic error message
unrecognized selector sent to instance xxx
SEL, IMP and their relation
- SEL is the method number, or method name, that was loaded into the table in memory by the read_image method when dyLD loaded the image.
- IMP is a function to achieve the pointer, looking for IMP is looking for the process of the function
- The relationship between the two: SEL is equivalent to the title of the book’s table of contents, IMP is the page number of the book. To find a specific function is to read a specific chapter in the book:
- The first thing we need to do is find the titles we want to look at which is title-sel
- Then find the corresponding page number according to the directory – IMP
- Find the concrete content – the concrete implementation of the method
extension
Method is implemented in assembly because
- Fast lookup process, i.e., method cache lookup, is designed to improve efficiency. Assembly code is the closest approximation to machine language, maximizing storage and execution time
- Assembly code has better support for dynamic and variable parameters
Binary search method:
- Search process: the method number in the table is arranged in ascending order, and the method number recorded in the middle of the table is compared with the method number to be searched. If the two are equal, the search succeeds; Otherwise, use the middle position record to divide the table into the former and the latter two sub-tables. If the method number of the search is greater than that of the middle position record, further search for the latter sub-table; otherwise, further search for the former sub-table. Repeat the above process until you find a record that meets the criteria, at which point the search succeeds. Or until the child table does not exist, in which case the search is unsuccessful.