An analysis of iOS runtime runtime

Source: Internet
Author: User
Tags set set

The runtime is an important concept in iOS and will be translated into runtime's C code execution during iOS. For example [target dosomething]; will be converted to OBJC) msgsend (target, @selector (dosomething)) to execute. This blog will be more comprehensive to explain the next runtime.

OC is a dynamic language that puts a lot of static language in the process of compiling and linking things into the runtime. The advantage of this dynamic language is that writing code can be more flexible, you can forward the message to the desired object, or arbitrarily exchange a method of implementation.

There are currently two versions of OC Runtime: Modern runtime and Legacy runtime. The modern runtime covers the 64-bit app,legacy runtime using the early 32-bit apps, so it's now free of the tubes.

(1) When we need to use the runtime interface, we need to import the header file: #import <objc/runtime.h>,runtime can do the following to get some information from the current class at run time:

Get the list of properties:



Get a list of methods:



Get a list of member variables:



Get the list of protocols:



So, we can probably summarize the role of runtime:

    • The program runs, dynamically creates a class;
    • In the program run, dynamically add properties/methods to a class, modify properties/methods;
    • Traverse all member variables/properties/methods of a class;


(2) method invocation:

If you invoke an instance method with an instance object, it will go to the object that the instance's Isa pointer points to (that is, the class object, yes, the class is also an object) operation. If a class method is called, it is manipulated into the object (the meta-class object) that the class's Isa pointer points to. The lookup process is as follows:

    • First, the method is called in the list of cached methods in the corresponding Operation object, and if found, turn to the corresponding implementation and execution;
    • If not found, the method is called in the list of methods in the corresponding action object, and if found, turn to the corresponding implementation;
    • If not found, go to the object that the parent pointer points to to perform the above steps;
    • And so on, if until the root class has not been found, turn to intercept the call;
    • If there is no way to rewrite the interception call, the program error;

Under the description, the method of overriding the parent class does not actually overwrite the parent class, except that the method is found in the current class object and will not be found in the parent class. If you want to invoke the parent class implementation of a method that has already been overridden, simply use the Super compiler flag, which skips the process of finding a method in the current class object at run time.


(3) Intercept call

An interception call is a chance to handle the four methods of rewriting nsobject before the calling method program crashes:



The following two methods need to be forwarded to other classes of processing:



    • The first method is to call a non-existent class method, call this method, the default return no, you can add their own processing and return yes;
    • The second method is similar to the first method, which deals with the instance method;
    • The third method is to redirect the non-existent method you call to a class that declares the method, and only needs to return a target with this method;
    • The fourth method is to package the non-existent method that you call into Nsinvocation to pass to you. After you have done your own processing, call Invokewithtarget: method to let a target trigger this method;

(4) The common use of runtime is to dynamically add methods at run time. We've talked about interception calls above, and dynamic add methods can be used in conjunction with interception calls. We can dynamically add a method based on the selector of the SEL type passed in. This way, even if we call a method that is not yet defined, the program will not crash.

The four parameters of Class_addmethod are:
    • Class CLS: Which class to add methods to;
    • SEL Name: Method selector selector;
    • IMP IMP: The realization of method, the realization of C method can be obtained directly. In the case of OC method, the implementation of the method can be obtained with + (IMP) instancemethodforselector;
    • const char *types: Signature of method


(5) The associated object is now ready to use a system class, and you need to add an additional attribute. We can use inheritance. But to add only one attribute, it is more wasteful to inherit a class. We can then use the runtime's associated properties.
Define a global variable and use its address as the key for the associated object:.

To set the associated object:



Four parameters of Objc_setassociatedobject:
    • ID object: To whom to set the associated object;
    • const void *key: The only key for the associated object is the global variable defined above;
    • ID Value: The associated object;
    • Objc_associatedpolicy: Association policy:





Two parameters of Objc_getassociatedobject:
    • ID object: Gets who's associated object;
    • const void *key: Gets the associated object based on this unique key;

(6) Method Exchange implements the exchange of two methods. For example, the A method and the B method are exchanged, and the code in the B method is executed when the A method is called. Vice versa. We generally implement the following code in the category of the class:.



(7) Runtime principle and mechanism runtime run, is the system at the time of the operation of some mechanism, the most important is the message mechanism. At the same time runtime is a relatively low-level C language API, belongs to a C language library, contains a lot of the underlying C language API. When the program runs, it turns into the C language code of runtime. OC implements dynamic invocation: [obj Maketext];
Runtime will convert the code to: Objc_msgsend (obj, @selector (maketext)) at compile time;
The Obj object has an Isa pointer,



All metaclass the ISA pointer points to the root metaclass, while the root metaclass points to itself. Root Metaclass is generated by inheriting the root class and is consistent with the root class struct members. @selector (Maketext): This is an Sel method selector. The main function of SEL is to quickly find the corresponding method's function pointer through the method name (Maketext), and then call the function. The SEL itself is an int-type address with the name of the method stored in the address. For a class, each method corresponds to a sel, so there cannot be 2 identically named methods in iOS, even if the parameter types are different.
Dynamic Lookup Process: The compiler converts code [obj Maketext], into objc_msgsend (obj, @selector (Maketext)), and in Objc_msgsend function, The class of obj is first found through the ISA pointer of obj. In class first go to the cache through the SEL to find the corresponding function method, if not found in the cache, and then go to MethodList to find, if not found in MethodList, then to superclass find. If found, the method is added to the cache to facilitate the next lookup, and the function pointer in method jumps to the corresponding function to execute.
Note: Why do I have to look for cache caches first? Because when a method is called, it is very likely that it will be called later. The students of software development should be able to understand.


(8) class in OC

The OC class is represented by the class type, which is actually a pointer to the Objc_class struct, and the class is defined in objc.h:


The Apple note also shows that class is an implied type that represents an OC class. View a definition of the objc_class struct in runtime.h:


It is also noted in the comments that class is substituted for struct objc_class later, so that the type definition can be easily used.


    • Version: The release information for the class, which defaults to 0;
    • Info: Class information, some bit flags used by the runtime;
    • Instance_size: The size of the instance variable of the class;
Among the parameters that we care about most are:
    • ISA: All classes themselves are also an object, and the object's class also has an Isa pointer, which points to the Metaclass meta-class;
    • Super_class: Refers to the parent class of the class, if the class is already the topmost root class (such as NSObject or Nsproxy), the super_class is null;


(9) An instance of the class Objc_object represents the struct body of an instance of a class, defined in Objc.h:.

The note also shows that Objc_object represents an instance of a class. The ID is then used to point to the instance structure of the class, which is also defined in Objc_h:.
A pointer to an instance. You can see that there is only one field in the struct, which is the ISA pointer to its class. Thus, when we send a message to an OC object, the runtime library finds the class to which the instance object belongs, based on the ISA pointer of the instance object.       The runtime library searches the method list of the class and the method list of the parent class for the method that corresponds to the message selector, and then runs the method when it is found. ID: A pointer to a objc_object struct type that can be converted to any kind of object, like void in C *.

(10) Meta-class Metaclass

All classes themselves are also an object that can send messages (that is, call class methods) to this object.

Nsarray *array = [Nsarray array];

The +array message was sent to the Nsarray class, and this Nsarray is also an object. Since it is an object, it is also a objc_object pointer that contains an ISA pointer to its class. In order to invoke the +array method, the ISA pointer for this class must point to a objc_class struct that contains these class methods. This requires a meta_class concept.

Meta_class is a class of class objects. When we send a message to an object, runtime looks for the method in the list of methods of the class to which the object belongs. When a message is sent to a class, it is looked up in the Meta_class method list of the class. Meta_class is important because it stores all the class methods of a class. Each class will have a separate meta_class, because the class methods of each class are not nearly identical.

Take a look at the diagram mentioned above, and there should be a deeper understanding now:


All Meta_class Isa points to the meta_class of the base class, in turn as their owning class. That is, the meta_class of any NSObject inheritance system uses NSObject's Meta_class as its own class, while the base class's Meta_class Isa pointer points to itself, thus forming a closed loop.


(11) Class and object manipulation functions

The operations of the class are mostly prefixed with class, and the objects are mostly prefixed with OBJC or object_.

    • Class name


Returns the name of a class in which the passed parameter is a class object.


    • Parent class (Super_class) and meta-Class (Meta_class)
Gets the parent class of the class:




Determines whether a given class is a meta-class:


To get the size of an instance variable:




In Objc_class, all member variables, attribute information is placed in the list Ivars, Ivars is an array, each element in the array is a pointer to Ivar.

    • Get information about instance member variables in a class



    • Get information about a class member variable



    • To add a member variable



    • Get a list of member variables




--------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------

The following number of property manipulation functions

    • Gets the specified property



    • Get Property List




    • To add a property to a class



    • Replace the properties of a class



--------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------

Here are the method operation functions:

    • Add method



    • Get instance method



    • Get class method



    • Get an array of all methods



    • Implementation of the replacement method



    • The specific implementation of the return method



    • Whether the class instance responds to the specified selector




--------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------


The protocol operation functions are as follows:

    • Add Agreement



    • Returns whether the class implements the specified protocol



    • Returns the list of protocols implemented by the class



--------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------


Get version versions as follows:

    • Get version number



    • Set the version number




(12) dynamic creation of classes

    • Create a new class and Meta class



    • Destroying a class and its associated classes



    • Registering a class created by Objc_allocateclasspair in your app


Objc_allocateclasspair function: If you want to create a root class, superclass specifies that nil,extrabytes is typically specified as 0, which is the number of bytes allocated to the tail of the class and meta-class object Ivars. Then use functions such as Class_addmethod,class_addivar to add methods, instance variables, and properties to the newly created class. Once this is done, you need to call the Objc_registerclasspair function to register the class, and then the new class can be used in the program.

Note: Instance methods and instance variables should be added to the class itself, and class methods should be added to the class's meta-class.


(13) Creating objects dynamically

    • To create a class instance



    • To create a class instance at the specified location



    • Destroying class instances




(14) Instance operation function

The instance manipulation function is primarily a series of manipulation functions for the instance object we create, which we can use to get the information we want from the instance object, such as the value of the variable in the instance object.

    • Returns a copy of the specified object



    • Frees the memory occupied by the specified object



--------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------

Functions for manipulating object instance variables

    • Modifying the value of an instance variable of a class instance


    • Gets the instance variable in the class object



    • Returns the value of an instance variable in an object




    • Set the value of an instance variable in an object



--------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------


Functions that operate on classes of objects

    • Returns the class name of the given object



    • Returns the class of an object



    • To set the class of an object



--------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------


Get class definition: Runtime automatically registers all classes defined in our code, and we can also create class definitions at run time and use the Objc_addclass function to register them.
    • Get a list of registered class definitions





    • Creates and returns a list of pointers to all registered classes




    • Returns the class definition for the specified class







    • Returns the meta-class of the specified class



(15) member variables, attributes

    • Ivar
Ivar is the type that represents the instance variable, which is actually a pointer to the Objc_ivar struct body.





    • objc_property_t
Objc_property_t is the type of the attribute that represents the OC declaration, which is actually a pointer to the Objc_property struct body.



    • objc_property_attribute_t
Defines the attributes of a property, which is a struct.



(16) Association object Association objects are similar to member variables, but are added at run time. The member variable Ivar is usually placed in the header file of the class declaration, or behind the @implementation of the class implementation. However, there is a drawback that you cannot add member variables to the category, or the compiler will make an error. The associated object can be imagined as an OC object (such as a dictionary), which is connected to an instance of the class by a given key. Because the C interface is used, key is a void pointer (const void *). The following memory management policies are used to manage this object. Same Top (5)



The SEL sel is called a selector, which is a selector pointer that represents a method, defined as follows:


The detailed definition of the objc_selector struct is not found in the header file, and the method's selector is used to represent the name of the run-time method. At compile time, OC generates a unique integer flag (an int type address) based on the name of each method, which is the SEL. The code shows:

The printing results are as follows:

Between two classes, if the inheritance relationship, as long as the method name is the same, then the method of the SEL is the same. Each method corresponds to an sel. So in the same class of OC (or in the inheritance system of a Class), there cannot be two methods with the same name, even if the parameter types are different. Therefore, OC does not exist the concept of overloading. Of course, different classes can have the same selector.     When instance objects of different classes perform the same selector, they will find their corresponding imp in the respective list of methods according to selector. All the SEL in the project consists of a set set, which is unique, so the SEL is unique. So, if we think of finding a method in this collection of methods, we just need to find the corresponding SEL for this method. The SEL actually hashes a string based on the method name, and the comparison of strings only needs to compare their addresses. In essence, the SEL is just a pointer to a method.
Imp imp is actually a function pointer pointing to the first address of the method implementation. Defined as follows:

The first argument is a pointer to self (the memory address of the class instance if it is an instance method, or a pointer to a meta class if it is a class method), the second parameter is the method selector (selector), followed by the actual argument list of the method.

() Method



See that there are sel and imp in the struct, which is equivalent to a mapping between SEL and Imp. With SEL, you can find the corresponding IMP, which invokes the implementation code of the method.
Objc_method_description defines an OC method, which is defined as follows:


(20) Method related operation function
    • Invokes the implementation of the specified method






    • Get Method Name


    • The implementation of the Return method



    • Gets a string that describes the method parameter and the return value type


    • Gets the type string that specifies the positional parameter of the method



    • return value type string for return method by reference


    • Returns the number of parameters for a method


    • Returns the method description struct for the specified method



    • Implementation of the Setup method



    • Implementation of exchange two methods



(21) Method Selector
    • Returns the name of the method specified by the given selector



    • Runtime registers a method, maps the method name to a selector, and returns the selector. When we add a method to the class definition, you must register a method name in runtime to get the selector for the method.



    • Registering a method in runtime


    • Comparison of two selectors



(22) method invocation process in OC, the message is not bound to the implementation of the method until run time. The compiler translates the message expression [receive message] into a call to a message function, which is objc_msgsend. This function takes the message receiver and the method masterpiece as the underlying parameter, as follows:

As you can see, the third parameter is a mutable parameter that is used to pass the argument list of the original method: Objc_msg_send (RECEIVE,SELECTOR,ARG1,ARG2). This function completes the dynamic binding of all things.
    • First it finds the selector corresponding to the implementation of the method. Because the same method might have different implementations in different classes, we need to rely on the recipient's class to find the exact implementation.
    • It invokes the implementation of the method and passes the recipient object and all parameters of the method to it.
    • Finally, it will implement the return value as his own return value.
The key to the message is that objc_class, there are two fields that we pay attention to when distributing the message:-pointers to the parent class;--the Sub-publication of a method of a class, i.e. methodlist;
The basic framework of the message:.




(23) Message forwarding when an object can receive a message, it goes through the normal method invocation process. By default, if the method is invoked as an [object message], the compiler will error if object cannot respond to message messages. But if it's a perform ... , you need to wait until the runtime to determine if object can receive a message. If not, the program crashes. In general, when we are not sure whether an object can receive a message, Respondstoselector is called first: to judge:


--------------------------------------------------------------------------------------------------------------- -------------------------------
When an object is unable to receive a message, the message forwarding (messages forwarding) mechanism is used. Through this mechanism, we can tell the object how to handle unknown messages. Message forwarding is divided into three steps:
    • dynamic method analysis;
    • Alternate recipients;
    • Full forwarding;

---Dynamic method resolves an object when it receives an unknown message, it first calls the class method of the owning class +resolveinstancemethod: Instance method or +resolveclassmethod: Class method. In this method, we have the opportunity to add a new processing method to the unknown message, but the premise of this method is that we have implemented the processing method, only need to be dynamically added to the class through the Class_addmethod function at runtime. As shown in the following code:
void FunctionForMethod1 (id self, SEL _cmd) {  NSLog (@ '%@,%p ', self, _cmd);} + (BOOL) Resolveinstancemethod: (SEL) sel {    NSString *selectorstring = Nsstringfromselector (sel);    if ([selectorstring isequaltostring:@ "Method1"]) {        Class_addmethod (Self.class, @selector (method1), (IMP) FunctionForMethod1, "@:");    }    return [Super Resolveinstancemethod:sel];}


---Alternate receiver if the message cannot be processed in the previous step, runtime continues to invoke the following methods:

If an object implements this method and returns a non-nil result, the object will be the new recipient of the message, and the message will be distributed to the object. Of course, this object cannot be self itself, otherwise there will be a wireless loop.

---Full message forwarding if the unknown message cannot be processed in the previous step, the only thing that can be done is to enable the full message forwarding mechanism, and the following methods are called:

At this stage, the runtime system will give the message recipient the last chance to forward the message to another object. The Nsinvocation object creates an object that represents the message, encapsulating all the details about the message that has not yet been processed in nsinvocation, including selector,target and parameters. We can forward messages to other objects in the Forwardinvocation method. At the same time we must override the following methods:

Runtime is broad and profound, the above is only the concept of runtime, principles and interface methods to explain, in the following blog I will be to implement some examples, to actually demonstrate the use of runtime. Welcome to the continuous attention Oh!


An analysis of iOS runtime runtime

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.