runtime 应用

发布时间:2019-08-06 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了runtime 应用脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
   1.什么是runtime?
runtime是一套底层的C语言API,包含很多强大实用的C语言数据类型和C语言函数,平时我们编写的OC代码,底层都是基于runtime实现的。

2.runtime有什么作用?
1.能动态产生一个类,一个成员变量,一个方法
2.能动态修改一个类,一个成员变量,一个方法
3.能动态删除一个类,一个成员变量,一个方法

3.常用的头文件
 #import <objc/runtime.h> 包含对类、成员变量、属性、方法的操作
 #import <objc/message.h> 包含消息机制
4.常用方法
class_copyIvarList()返回一个指向类的成员变量数组的指针
class_copyPropertyList()返回一个指向类的属性数组的指针
注意:根据Apple官方runtime.h文档所示,上面两个方法返回的指针,在使用完毕之后必须free()。

ivar_getName()获取成员变量名-->C类型的字符串
property_getName()获取属性名-->C类型的字符串
-------------------------------------
typedef struct objc_method *Method;
class_getInstanceMethod() 
class_getClassMethod()以上两个函数传入返回Method类型
---------------------------------------------------
method_exchangeImplementations()交换两个方法的实现
5.runtime在开发中的用途
1.动态的遍历一个类的所有成员变量,用于字典转模型,归档解档操作
代码如下:
  • (void)viewDidLoad {

     [super viewDidLoad];    
     /** 利用runtime遍历一个类的全部成员变量     
         1.导入头文件<objc/runtime.h>     */    
     unsigned int count = 0;   
    /** Ivar:表示成员变量类型 */    
     Ivar *ivars = class_copyIvarList([BDPerson class], &count);//获得一个指向该类成员变量的指针   
    for (int i =0; i < count; i ++) {        

    //获得Ivar

     Ivar ivar = ivars[i];        //根据ivar获得其成员变量的名称--->C语言的字符串      
     const char *name = ivar_getName(ivar);       
      NSString *key = [NSString stringWithUTF8String:name];      
     NSLog(@"%d----%@",i,key);

    }

       free(ivars);

    }
    运行结果如下:

    runtime 应用


    成员变量遍历输出结果.png

runtime 应用

获取一个类的全部属性:


获取类的属性的代码实现.png

结果如下:

runtime 应用

输出结果.png

应用场景:

可以利用遍历类的属性,来快速的进行归档操作。
将从网络上下载的json数据进行字典转模型。

注意:归档解档需要遵守<NSCoding>协议,实现以下两个方法
  • (void)encodeWithCoder:(NSCoder *)encoder{

       //归档存储自定义对象    
       unsigned int count = 0;  
       //获得指向该类所有属性的指针   
       objc_property_t *properties =     class_copyPropertyList([BDPerson class], &count);   
       for (int i =0; i < count; i ++) {        
       //获得        
       objc_property_t property = properties[i];        //根据objc_property_t获得其属性的名称--->C语言的字符串       
      const char *name = property_getName(property);   
      NSString *key = [NSString   stringWithUTF8String:name];       
      //      编码每个属性,利用kVC取出每个属性对应的数值            
      [encoder encodeObject:[self valueForKeyPath:key] forKey:key]; 
    }}
    
  • (instancetype)initWithCoder:(NSCoder *)decoder{

         //归档存储自定义对象    
           unsigned int count = 0;   
        //获得指向该类所有属性的指针   
          objc_property_t *properties = class_copyPropertyList([BDPerson class], &count);   
          for (int i =0; i < count; i ++) {       
          objc_property_t property = properties[i];        //根据objc_property_t获得其属性的名称--->C语言的字符串       
          const char *name = property_getName(property); 
            NSString *key = [NSString stringWithUTF8String:name];        //解码每个属性,利用kVC取出每个属性对应的数值      
          [self setValue:[decoder decodeObjectForKey:key] forKeyPath:key];  

    }

    return self;

    }
    二、交换方法
    通过runtime的method_exchangeImplementations(Method m1, Method m2)方法,可以进行交换方法的实现;一般用自己写的方法(常用在自己写的框架中,添加某些错措施)来替换系统的方法实现,常用的地方有:

    数组中,越界访问程序会崩,可以用自己的方法添加判断防止程序出现崩溃数组或字典中不能添加nil,如果添加程序会崩,用自己的方法替换系统防止系统崩溃
    ...
    代码实现如下:

    运行程序崩溃.png

    runtime 应用


添加一个分类实现方法交换.png

runtime 应用


再次运行刚才的程序:

runtime 应用

脚本宝典总结

以上是脚本宝典为你收集整理的runtime 应用全部内容,希望文章能够帮你解决runtime 应用所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。