Overview: runtime, also called runtime, is a low-level C language API and one of the cores of iOS system. A developer can send a message to any object during the encoding process, but only decides to send a message to the receiver during the compilation stage. How the receiver responds and processes the message depends on the runtime.
? In C language, the compiler decides which function to call, while the function of OC is a dynamic calling process. The compiler can't really decide which function to call, and only when it is actually running will it find the corresponding function to call according to the function name. OC is a dynamic language, which means that it needs not only a compiler, but also a runtime system to dynamically create classes and objects, and deliver and send messages.
1. message forwarding
The main function of the runtime is message passing. If the message is not found in the object, it will be forwarded. Objective-C is a dynamic language, which means that it needs not only a compiler, but also a runtime system to dynamically create classes and objects, and pass and forward messages. The core of the runtime is messaging.
(1) the process of message delivery
An object's method [obj test], the compiler turns it into a message to send objc _ msgsend (obj, test), and the process executed at runtime is as follows.
A. first find its class through the isa pointer of obj.
B. Find the test in the method list of the class.
If test is not found in the class, continue to look for it in its superclass.
D. Once the function test is found, execute its IMP.
Because of the efficiency problem, it is unreasonable to traverse the objc_method_list once for each message, so it is necessary to cache frequently called functions to improve the efficiency of function query. This is the role of another important member of objc_class, objc_cache. After finding the test, use the test's method_name as the key and method_imp as the value. When you receive the test message again, you can look it up directly in the cache.
Class object (objc_class)
The Objective-C class is represented by a class type, which is actually a pointer to the objc_class structure. Many variables are defined in the struct objc_class structure. The pointer to the parent class, class name, version, instance variable list (ivars), method list (cache) and protocol list (protocol) are stored in this structure. In this way, a class object is a structure struct objc_class, and the data stored in this structure is metadata.
Understanding the runtime means understanding the data storage of iOS and the relationships and functions among its classes, instances, class objects and metaclasses.
(2) message forwarding mechanism
In the final analysis, the essence of all method calls in Objective-C is to send messages to objects.
1. Create a method in a class -(void) test.
2.2. The IOS system creates a number SEL(test) for this method and adds it to the method list.
3. When the method is called, the system looks up the method in the method list and executes the method when it is found.
So calling a method will send a message once, which will be found in the method list of this class. If it is not found in this class, it will be found in the parent class of this class. If the parent class is still not found, it will be searched to the root of the inheritance tree. If it is not found or the message forwarding is unsuccessful, it will be reported as an unrecognized selector error.
1. dynamic method analysis
The Objective-C runtime will call +resolveInstanceMethod: or? +resolveClassMethod: Gives you an opportunity to provide a function implementation. If you add a function and return YES, the runtime will restart the message sending process. As shown in the figure below:
Although there is no foo implementation function:, the fooMethod function is dynamically added through class_addMethod (), and the function is successfully printed. If reslove returns NO, the runtime will go to the next step: forwardingTargetSelector.
2. Direct message forwarding
If the target object implements forwardingTargetSelector, the runtime will call this method at this time, giving you an opportunity to forward this message to other objects.
As can be seen from the figure, we passed the method of the current class to the parent class through the forwardingTargetForSelector method, and the printing was successful.
3. Complete message forwarding
If the unknown message cannot be processed in the previous step, the only thing you can do is to start the message forwarding mechanism. First, it sends a methodSignatureForSelector message to get the parameters and return value types of the function. If methodSignatureForSelector returns nil, the runtime will issue doesNotRecognizeSelector. If the signature function is returned, the runtime will create a NSInvocation object and send a forwardInvocation message to the target object.
Practical application of runtime
1. Use the runtime exchange method
2. Dynamic addition method (not well understood at present)
3. Add attributes to the classification
4. Message forwarding (hot update) to solve Bug(JSPatch)