Summary of common Runtime examples for iOS development and iosruntime examples

Source: Internet
Author: User
Tags list of attributes

Summary of common Runtime examples for iOS development and iosruntime examples

Some friends often ask for something about Runtime on Q in private, and ask me if I have any blog about Runtime. I have never summarized it before. Previously, I talked about some usage when parsing the source code of a third-party framework, that is, the Runtime used in these third-party frameworks. For example, attribute Association and dynamic attribute acquisition. This blog summarizes some of its frequently-used methods based on the topic "Runtime". Of course, the "empty talk about the country by mistake" still relies on the Demo of this blog.

The Runtime content of this blog is as follows: dynamically obtains the class name, dynamically obtains the class member variables, dynamically obtains the class attribute list, dynamically obtains the class method list, dynamically obtains the protocol list followed by the class, and dynamically adds new methods. and instance methods of the class, such as exchange, dynamic attribute Association, and message sending and message forwarding mechanisms. Of course, this blog summarizes the features that are often used during running, not all of the Runtime content.

 

1. Build a Runtime test case

The content of this blog is based on examples. Therefore, in this blog, we first build our test class, and Runtime will perform related operations on this class. Below is the Demo directory involved in this blog. The RuntimeKit class above is a simple encapsulation of common Runtime functions, the TestClass and related categories below are the objects to be operated by Runtime. The content in TestClass and category is described in detail below.

  

 

Below are the main parts of our test class TestClass. Because TestClass is a specialized test class, the content involved should be as comprehensive as possible. TestClass complies with the NSCoding and NSCopying protocols and adds public attributes, private attributes, Private member variables, public instance methods, private instance methods, and class methods to it. The added content will be our Runtime operation object. The following TestClass categories will be introduced later when using Runtime.

  

  

  

 

2. RuntimeKit Encapsulation

Next, let's take a look at the content in RuntimeKit, which encapsulates the commonly used methods of Runtime. It mainly obtains some attributes and methods of the class dynamically, as well as addition of dynamic methods and exchange of methods. There are still a lot of dry goods in this part.

1. Get the class name

It is relatively simple to obtain the Class name dynamically. You can use class_getName (Class) to obtain the Class name at runtime. The class_getName () function returns a char pointer, that is, a string type in C language. Therefore, we need to convert it to the NSString type and then return it. The + fetchClassName below: The method is the method we encapsulate to get the class name, as shown below:

  

 

2. Get member variables

Below this + fetchIvarList: This method is our encapsulated method to obtain the member variables of the class. Of course, we can use ivar_getTypeEncoding () to obtain the type of the corresponding member variable when getting the member variable. Use ivar_getName () to obtain the name of the corresponding member variable. Below is the encapsulation of the function for getting member variables. An array is returned, and the elements of the array are a dictionary. The dictionary stores the names and types of corresponding member variables.

  

The following is the member variable of the TestClass class obtained by calling the above method. Of course, there is no private or public distinction at runtime, as long as it is a member variable, it can be obtained. Adding a member attribute to a class in OC is actually adding a member variable, a getter and a setter method. Therefore, the retrieved member list must contain Member attributes. However, the names of member attributes must be distinguished by underscores. We can also obtain the member variable type. The _ var1 below is the NSInteger type, and the q letter is obtained dynamically, which is actually the NSInteger symbol. I indicates the int type, c indicates the Bool type, d indicates the double type, and f indicates the float type. Of course, these basic types are replaced by a letter. If they are reference types, they are directly strings. For example, the NSArray type is "@ NSArray ".

  

 

3. Get member attributes

The above is the member variable of the class, then the + fetchPropertyList below: gets the member attribute. Of course, only the Member attributes are obtained at the moment, that is, the member variables with the setter or getter methods. The following describes the list of attributes obtained using class_copyPropertyList (Class, & count), and obtains the name of each attribute through property_getName () through the for loop. Of course, the name obtained by using property_getName () is still a char pointer of the C language, so we also need to convert it to the NSString type and put it in the array and return it. As follows:

  

Below is all the attributes of TestClass obtained by calling the above method. Of course, dynamicAddProperty is dynamically added to TestClass using Runtime, so it can also be obtained. Of course, the names of the obtained attributes are distinguished by their corresponding member variables. The front and side of the member attributes are not underlined.

  

 

4. Obtain the instance method of the class

Next, we will encapsulate the function of getting the instance method list of the class. The + fetchMethodList below is the function that we encapsulate to get the instance method list of the class. In the function below, you can use the class_copyMethodList () method to obtain the instance method list of the class, and then use method_getName () to obtain the name of each method through the for loop, then, convert the method name to the NSString type, store it in the array, and return it. The Code is as follows:

  

Below is the result of the above method running on TestClass, which prints all the instance methods of TestClass. Of course, the getter and setter methods of member attributes must also be included. Of course, methods in the TestClass category must also be available. The result is as follows:

  

 

5. Obtain the protocol list

The following describes how to obtain the protocol list that our class complies with. We mainly use class_copyProtocolList () to obtain the list, and then use protocol_getName () to obtain the name of the Protocol in the for sequence, finally, convert it to the NSString type and put it into the array to return the result.

  

Below is the list of protocols that the TestClass class follows:

  

 

6. Dynamic addition method implementation

The following describes how to dynamically add methods and implementations to corresponding classes. The + addMethod method below has three parameters. The first parameter is the class of the method to be added, the second parameter is the SEL of the method, and the third parameter is the sel of the method implementation. The following method will be used for sending and forwarding messages later. The following describes how to use class_getInstanceMethod () and method_getImplementation () to obtain the corresponding SEL. The IMP below is actually the abbreviation of Implementation. After obtaining the corresponding method Implementation, call the class_addMethod () method to bind IMP with SEL. The procedure is as follows.

  

 

7. Exchange Methods

The following describes the implementation of the two methods of the class for exchange. If you exchange methods between MethodA and MethodB, the content of MethodB will be executed when MethodA is called, and vice versa.

  

The code below is a test of the above method. Below is a category of TestClass, in which methods in the category are replaced with methods in TestClass. In other words, method1 and method2 are replaced. After replacement, method2 called in method2 is actually called method1. This feature is often used in third-party libraries and has achieved the goal of AOP programming.

  

 

3. Attribute Association

To put it bluntly, the attribute Association function dynamically adds corresponding attributes to our classes in the categories. If you have read the previously published blog about source code parsing of the Masonry framework, it is no stranger to the attribute Association below. In the Masonry framework, a constraint array is added to the UIView category using Runtime attribute Association to record all constraints added to the current View. The following describes how to add a dynamicAddProperty attribute to the TestClass class through the objc_getAssociatedObject () and objc_setAssociatedObject () methods in the TestClass category. The attribute list we obtained above contains the dynamically added member attributes.

The code for Attribute Association is shown below.

  

 

Iv. Message Processing and message forwarding

In Runtime, we have to mention the OC message processing and message forwarding mechanisms. Of course, there are also a lot of related information on the Internet. This blog will talk about message processing and message forwarding for the sake of integrity.When you call a class method, you first query the method cache list in this class. If the implementation of this method is found in the cache list, it is executed, if it cannot be found, search in the list of parties in this class. Find the corresponding method implementation in the category list and call it. If not, search for it in the parent class. If the implementation of the corresponding method is found in the method list of the parent class, execute the following steps..

When you call a method in the cache list, the method list in this class and the method list of the parent class cannot find the corresponding implementation, there will be several steps in the middle of the program crash phase for you to save. Next, let's take a look at the steps.

1. Resolve Method)

When the implementation of class methods cannot be found in the corresponding class and parent class, the + resolveInstanceMethod will be executed: This class method. If this method is not overwritten in the class, NO is returned by default. If NO is returned, NO processing is performed. Proceed to the next step. If YES is returned, the implementation method cannot be found in this method. In this method, we can add a method implementation for the SEL that cannot be found. After adding the method, we will execute the method implementation. In this way, when a class calls a method that does not exist, it will not crash. The procedure is as follows:

  

 

2. Fast message forwarding

If the preceding message is not processed, + resolveInstanceMethod: when NO is returned, the next message is forwarded, that is,-forwardingTargetForSelector :. This method returns a class object. The class object has the implementation of SEL. When this method cannot be found is called, it will be forwarded to SecondClass for processing. This is also called message forwarding. When the method returns self or nil, it indicates that the corresponding method is not forwarded, so proceed to the next step.

  

 

3. General Message forwarding

If you do not forward messages to other class objects, you can only process them yourself. If the above method returns self, it will execute-methodSignatureForSelector: The method to obtain the parameters of the method and the returned data type, that is, the method gets the signature of the method and returns it. If the above method returns nil, the message forwarding ends, the program crashes, and no crash information is found for the corresponding method implementation.

When + resolveInstanceMethod: NO is returned, the following method is executed, and the method is forwarded to SecondClass as follows:

  

 

Today's blog will come here first. Of course there are other Runtime things not covered in this blog. If we encounter it when parsing the source code of the open source library in the future, we will talk about it separately. By convention, the Demo attached to this blog will still be shared on Github. below is the sharing link.

Github source code share link: https://github.com/lizelu/ObjCRuntimeDemo

 

Related Article

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.