Analysis of runtime Running Mechanism in iOS

Analysis of runtime Running Mechanism in iOS


http://blog.csdn.net/fuzheng0301/article/details/46898405


First, consider two questions:

First question,
1) What is the mechanism of runtime implementation, how to use it, and what is it generally used for?  
I'm not going to beat around the bush with you on this question. I'll tell you directly.
runtime is a relatively low-level pure set C Language API, which belongs to a C language library, contains many low-level C language APIs.  
In the OC code we usually write, when the program runs, it turns into the C language code of runtime. Runtime is the backstage worker of OC.
For example, in the following method of creating objects,
Examples:
OC : 
[[MJPerson alloc] init] 
runtime : 
objc_msgSend(objc_msgSend("MJPerson" , "alloc"), "init")


Second question
What does runtime do? Where is it used? How to use it?  
runtime belongs to the bottom of OC and can perform some very low-level operations (OC is unrealistic and difficult to implement).

  • In the process of running a program, create a class dynamically (such as the underlying implementation of KVO)

  • In the process of program running, add attribute method dynamically for a class, modify attribute value method

  • Traversing through all member variables (attributes) all methods of a class
    For example, when we need to archive and archive the attributes of a class, there are many attributes. At this time, we will write many corresponding codes, but if we use runtime, we can set them dynamically.

2. To learn the runtime mechanism, we should first understand the following questions.

       Objective-C It is a compiled and dynamic language (oc is a static type language emphasized here), which is common in development languages. Most of the general dynamic languages are interpretative languages. OC is a dynamic language even if it is compiled. That's because of the RunTime mechanism.

1. Related header files and functions
1 > Header file

  • Using the header file, we can see the various methods in runtime!

2 > Relevant Applications

  • NSCoding (archiving and archiving, using runtime to traverse all attributes of model objects)
  • Dictionary --> Model (using runtime to traverse all attributes of the model object, extract the corresponding value from the dictionary according to the attribute name, and set it on the attributes of the model)
  • KVO (using runtime to dynamically generate a class)
  • For encapsulation frameworks (change as you want)
    This is the direction of our runtime mechanism as long as it is applied.

3 > correlation function

    1. class_copyPropertyList Gets a copy of the membership list array

    2. Proper_getName gets the member name

    3. class_getInstanceVariable to get Ivar of member object

    4. object_getIvar takes values from Ivar objects

    5. object_setIvar assignment function

    6. objc_msgSend: Sending messages to objects

    7. class_copyMethodList: Traversing through all methods of a class

    8. class_copyIvarList: Traversing through all member variables of a class

    9,class_.....

    These are the functions we have to know when we learn runtime!

2. Necessary common sense
1 > Ivar: Membership variables
2 > Method: Membership Method
From the example above, we can see that the member variables we defined can be created dynamically using Method.


Third, we can see clearly the inheritance hierarchy between classes and objects in OC through a graph.

Note: The isa pointer in all metaclasses points to the root metaclass, while the root metaclass points to itself. The root metaclass is generated by inheriting the root class, which is identical to the members of the root class structure, except that the ISA pointer of the root metaclass points to itself.

1. When we call the object method of an object, it will first find the method in the class method Lists pointed by its isa pointer, and if it cannot find it, it will find its parent class through the class super_class pointer, and then find the method from its method Lists. If it still cannot find it, it will continue to use super_cl. Ass looks up the parent structure until the root class.

2. When we call a class method, it first finds the metaclass through its isa pointer and finds it from its methodLists. If it cannot find it, it finds the metaclass structure of the parent class through the super_class pointer of the metaclass. Then it finds the method from the methodLists. If it still can't find it, it finds the metaclass structure of the parent class. Continue to look up the parent structure of the upper class through super_class until the root metaclass;


Fourth, let's take a look at the code implementation:

1. Create a class

CustomClass.h


  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface CustomClass : NSObject  
  4.   
  5. @property (nonatomic , strongNSString *age;  
  6.   
  7. - (void)test;  
  8.   
  9. @end  

CustomClass.m


  1. #import "CustomClass.h"  
  2.   
  3. @implementation CustomClass  
  4.   
  5. - (void)test  
  6. {  
  7.     NSLog(@"Here is CustomClass");  
  8.       
  9. }  
  10.   
  11. @end  

Next, create a category to implement the RunTime mechanism

NSObject+RunTimeTest.h


  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface NSObject (RunTimeTest)  
  4.   
  5. //Create a class dynamically, and then assign values to the age attribute of the class.  
  6. - (id) testRunTime:(NSString *)classname age:(NSString *)age;  
  7.   
  8.   
  9. @end  

NSObject+RunTimeTest.m


  1. #import "NSObject+RunTimeTest.h"  
  2. #import <objc/runtime.h>  
  3. #import "CustomClass.h"  
  4.   
  5.   
  6. @implementation NSObject (RunTimeTest)  
  7.   
  8. - (CustomClass *)testRunTime:(NSString *)classname age:(NSString *)age  
  9. {  
  10.     //Number of property Count member attributes  
  11.     unsigned int propertyCount = 0;  
  12.     /* objc_property_t According to the explanation of the Apple document: An opaque type that represents an Objective-C declared property. 
  13.   Personal Understanding: An object of any type represents an attribute member of an oc declaration.*/  
  14.     /* class_copyPropertyList   
  15.      Document: Return Value 
  16.      An array of pointers of type objc_property_t describing the properties declared by the class. Any properties declared by superclasses are not included. The array contains *outCount pointers followed by a NULL terminator. You must free the array with free(). 
  17.      Personal Understanding: The main two meanings: return an array pointer, type objc_property_t, remember free, release. 
  18.      */  
  19.     objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);  
  20.     for (unsigned int i = 0; i < propertyCount; i++) {  
  21.   objc_property_t property = properties[i];  
  22.   //Get the name of the member  
  23.   NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];  
  24.   NSLog(@"propertyName = %@ -- Membership name",propertyName);  
  25.     
  26.   //Ivar to retrieve member content  
  27.   Ivar iVar = class_getInstanceVariable([self class], [propertyName UTF8String]);  
  28.   //In fact, the above line of access code is for the sake of insurance, basically can not get the content. Because the member's name will be preceded by "" by default.  
  29.   if (iVar == nil) {  
  30.       iVar = class_getInstanceVariable([self class], [[NSString stringWithFormat:@"_%@",propertyName] UTF8String]);  
  31.   }  
  32.     
  33.   //Value  
  34.   id propertyVal = object_getIvar(self, iVar);  
  35.   NSLog(@"propertyVal = %@ --value",propertyVal);  
  36.     
  37.          
  38.     
  39.     
  40.   //Dynamic creation of classes  
  41.   Class varClass = NSClassFromString(classname);  
  42.   id varObj = [[varClass alloc] init];  
  43.   //Call the method of the newly created class, here we must mainly introduce the corresponding header file, otherwise it will be good to call the method.  
  44.   [varObj test];  
  45.     
  46.   Ivar iVarObj = class_getInstanceVariable(varClass, [@"_age" UTF8String]);  
  47.     
  48.     
  49.     
  50.   object_setIvar(varObj, iVarObj, age);  
  51.     
  52.     
  53.   return varObj;  
  54.     }  
  55.     return nil;  
  56.       
  57.       
  58.       
  59. }  
  60.   
  61. @end  

test:

ViewController.m


  1. #import "NSObject+RunTimeTest.h"  
  2. #import "CustomClass.h"  
  3.   
  4. @interface ViewController ()  
  5.   
  6. @property (nonatomic , strongNSString *name;  
  7.   
  8.   
  9. @end  
  10.   
  11. @implementation ViewController  
  12.   
  13. - (void)viewDidLoad {  
  14.   [super viewDidLoad];  
  15.   // Do any additional setup after loading the view, typically from a nib.  
  16.     
  17.   _name = @"xiaonan";  
  18.   CustomClass *tmp = [self testRunTime:@"CustomClass" age:@"098"];  
  19.   NSLog(@"tmp.age = %@",tmp.age);  
  20.     
  21.     
  22. }  

Results Output:

  1. 2014-11-29 17:16:55.483 TestRunTime 2 [21001:176367] propertyName = name -- member name
  2. 2014-11-29 17:16:55.483 TestRunTime 2 [21001:176367] propertyVal = xiaonan -- value
  3. 2014-11-29 17:16:55.484 TestRunTime 2 [21001:176367] CustomClass
  4. 2014-11-29 17:16:55.484 TestRunTime2[21001:176367] tmp.age = 098  

Keywords: Attribute C iOS encoding

Added by steveDD on Wed, 17 Jul 2019 02:15:59 +0300