This article focuses on the runtime mechanisms that are primarily involved in OC development:
Run-time work:
Runtime work in OC: The design pattern of the OC language determines that the program can be postponed from compile and link to runtime whenever possible. Whenever possible, OC always uses a dynamic approach to solve the problem. This means that the OC language requires not only a compiler, but also a runtime system to execute the compiled code. The runtime system here plays a role similar to the OC language operating system, and OC works based on that system.
simple application at runtime:
The OC 2.0 Runtime System Reference Library describes the data structure and function interfaces of the OC runtime. Programs can interact with the OC runtime system through these interfaces. For example: Add a class or method, or get a list of definitions for all classes.
Two versions of runtime:
The OC runtime system has two versions, the previous version is primarily used in OC1.0, the current version is for OC2.0, and in earlier versions all subclasses of the class must be recompiled if the instance variable layout in the class was changed. In the current version, if you change the layout of instance variables in a class, you do not need to recompile any subclasses of the class. Early risers are generally used for 32-bit programs in Max OS X systems and are considered to be all current versions.
Interactive approach:
1, through the OC source code:
When compiling OC classes and methods, the compiler automatically creates some data structures and functions for implementing the statement's dynamic nature. The primary function of the runtime system is to send messages based on expressions in the source code.
2, through the Foundation Framework class NSObject method:
Most of the classes in the Cocoa program are subclasses of the NSObject class, so most of them inherit the NSObject class, thus inheriting the behavior of the NSObject class. In some cases, however, the NSObject class simply defines a template to accomplish something without providing all the required code, and some nsobject methods simply get information from the runtime system, allowing the object to perform a certain degree of self-examination. Such as: Class returns the classes of the object: Iskindofclass: And Ismemberofclass: Checks whether the object is in the specified class inheritance system; Respondstoselector: Checks the message that the object can specify accordingly ; Conformstoprotocol: Checks whether the object implements the method of the specified protocol class; Methodforselector: Returns the address of the specified method implementation.
3, directly by invoking the function of the runtime system:
The runtime system is a dynamic library of public interfaces, consisting of a collection of data structures and functions, and the Declaration header files for these data structures and functions are in/USR/INCLUDE/OBJC. These functions support the same functions as OC with a pure C function. bummed Some functions form the basis of the NSObject class method. These functions make it possible to access the runtime system interfaces and provide development tools. Although they are not required in the OC program in most cases, some functions are sometimes useful for programs such as OC.
message mechanism at runtime:
1, obtain the method address:
The only way to avoid dynamic binding is to get the address of the method and invoke it directly like a function call. When a method is called many times, and you want to save the cost of sending a message each time the method is called, it is useful to invoke the method using the method address.
Using the Methodforselector: Method in the NSObject class, you can obtain a pointer to a method implementation, and you can call the method implementation directly using that pointer. Methodforselector: The returned pointer and the assigned variable type must be exactly the same, including both the parameter type of the method and the type of return value that are considered in the type recognition.
Avoiding dynamic binding reduces the overhead of most messages when the specified message is repeatedly sent multiple times.
2. Objc_msgsend function
In OC, the message is not bound to the method until it is run, and the compiler converts a message expression into a call to the message function Objc_msgsend. The function has two main parameters: the message receiver and the message corresponding to the method name (that is, the method's selection).
Objc_msgsend (receiver, selector), while receiving any number of parameters in the message: Objc_msgsend (receiver, selector, arg1, arg2,...)
The message function does everything needed to bind dynamically, finds the corresponding method implementation, and passes the message receiver object and parameters to the found method implementation, and returns the return value of the method implementation as the return value of the function.
When the object receives a message, the message function first finds the method table of the class corresponding to the object based on the object's Isa pointer, and looks for the method selection for the message from the table, and if it is not found, Objc_mssend will find it from the parent class, knowing the NSObject class. Once the selection is found, Objc_msgsend is invoked with the message receiver object as a parameter and the corresponding method of the selection is invoked. This is how you choose the method implementation in the runtime system. In object-oriented programming, it is generally called the process of dynamic binding of methods and messages.
To speed up the processing of messages, the runtime system typically places the used method selection and the address of the method implementation into the cache. Each class has a separate cache, including inherited methods and methods defined in the class. The message function first checks the cache of the class that corresponds to the message receiver object (theoretically, if a method is used once, it is likely to be reused). If the required method selection is already in the cache, the message is only a little slower than the function call. If the program is running long enough, almost every message can find a method implementation in the cache. When the program runs, the cache will also increase as new messages increase.
3. Using Hidden parameters
When Objc_msgsend finds the implementation of the method, it calls the implementation of the method directly and passes all parameters in the message to the method implementation, and also passes two hidden parameters:
1. Object receiving message: The message receiver object can be referenced by self
2, method selection: By selecting the standard _cmd to refer to the method itself.
Although these parameters are not declared, they can still be referenced in the source code.
Dynamic Method parsing:
1, dynamic method Analysis:
@dynamic property name; Indicates that the compiler needs to dynamically generate the corresponding method for this property.
By implementing Resolveinstancemethod: and Resolveclassmethod: To dynamically implement a given selection of object methods or class methods.
The OC method can be thought of as a C function with at least two parameters, self and _cmd. A function can be added to a method of a class by means of the Class_addmethod method, as follows:
void Dynamicmethodimp (id self, SEL _cmd) {
Implementation ...
}
+ (BOOL) Resolveinstancemethod: (SEL) SEL {
if (sel = = @selector (resolvethismethoddynamically)) {
Class_addmethod ([Self class], SEL, (IMP) dynamicmethodimp, "[email protected]:");
return YES;
}
return [Super Resolveinstancemethod:sel];
}
Before entering the message forwarding mechanism, Respondstoselector: and Instancesrespondtoselector: will be called first. You can provide an IMP for the incoming selection in both methods. If you implement the Resolveinstancemethod: method but still want the normal message forwarding mechanism, you just need to return NO.
2. Dynamic Loading
The OC program can link and load new classes and category classes at run time. There is no difference between the newly loaded class and the class that is loaded when the program starts.
Dynamic loading can be used in many places, for example, a module in a system configuration is dynamically loaded.
Application Scenarios:
In a COCOA environment, dynamic loading is typically used to customize the application. Modules written by other programmers can be loaded at run time (similar to the interface build loading a custom palette and the system configuration program loading a custom module). These modules extend their own programs in a permissive way, without having to define or implement them on their own. provided themselves with the framework, two other programmers provided the implementation.
Message Forwarding:
1. Message forwarding
If an object receives a message that cannot be processed, the runtime sends an forwardinvocation message to the object before it throws an error: The unique parameter of the message is an object of type nsinvocation that encapsulates the original message and message parameters. You can implement Forwardinvocation: methods to do some default processing of messages that cannot be processed, or to avoid errors being thrown in some other way.
When an object does not respond to a method implementation and is unable to respond to a message, the runtime notifies the object through a forwardinvocation: message. Each object is integrated from the NSObject class with the Forwardinvocation: method. However, the method implementation in NSObject simply calls the Doernotrecognizeselector:. By implementing your own Forwardinvocation: methods you can forward messages to other objects in the method implementation.
Messages can be forwarded via the Invokewithtarget: method:
-(void) Forwardinvocation: (nsinvocation *) aninvocation {
if ([Someotherobject respondstoselector:[aninvocation selector]])
[Aninvocation Invokewithtarget:someotherobject];
Else
[Super Forwardinvocation:aninvocation];
}
Forwardinvocation: The method is like a distribution center for unrecognized messages that forwards these messages to different receive objects. It can translate a message into another message, or simply "eat" some messages, so there is no response and no error. Forwardinvocation: Methods can also provide the same response to different messages, all depending on the implementation of the method. The method provides the ability to link objects that are not connected to the message chain.
Note: The Forwardinvocation: method is called only if the message is not responding properly in the message acceptance object. So, if you want your object to forward CLICKBTN: messages to other objects, your object cannot have Clickbtn: method. Otherwise, forwardinvocation: it will not be possible to be called.
2. Message forwarding and multiple inheritance
Message forwarding is much like integration and can be used to simulate multiple inheritance in an OC program. An object responds to a message by forwarding it, as if the object had borrowed from another class or "inherited" a method implementation. The message in one class is forwarded to another class through the Forwardinvocation: method.
3. Message Agent Object
4. Message forwarding and class inheritance
In-depth analysis of the runtime mechanism of iOS development