runtime的基本应用

摘要:
运行时是一组底层C语言API,包括许多强大实用的C语言数据类型和C语言函数。我们通常编写的底层OC代码基于运行时。将从网络下载的json数据转换为字典模型。

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);
}
}

运行结果如下:

runtime的基本应用第1张
成员变量遍历输出结果.png


获取一个类的全部属性:

runtime的基本应用第2张
获取类的属性的代码实现.png


结果如下:

runtime的基本应用第3张
输出结果.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,如果添加程序会崩,用自己的方法替换系统防止系统崩溃
  • ...
    代码实现如下:
    runtime的基本应用第4张
    运行程序崩溃.png
    runtime的基本应用第5张
    添加一个分类实现方法交换.png

    再次运行刚才的程序:
    runtime的基本应用第6张
    最终运行结果图.png

免责声明:文章转载自《runtime的基本应用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Phaser3学习笔记[python库]turtle库总结下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Go日志库使用-logrus

golang日志库 golang标准库的日志框架非常简单,仅仅提供了print,panic和fatal三个函数对于更精细的日志级别、日志文件分割以及日志分发等方面并没有提供支持。 所以催生了很多第三方的日志库,但是在golang的世界里,没有一个日志库像slf4j那样在Java中具有绝对统治地位。golang中,流行的日志框架包括logrus、zap、ze...

golang 之GPM模型

1、Golang调度器的由来 2、Goroutine调度器的GMP模型及设计思想 3、Goroutine调度场景过程全图文解析 早期的单进程操作系统,面临2个问题: 1.单一的执行流程,计算机只能一个任务一个任务处理。 2.进程阻塞所带来的CPU时间浪费。 多进程/线程时代有了调度器需求: 进程拥有太多的资源,进程的创建、切换、销毁,都会占用很长的时间,...

SAP BW Query常见的性能问题 沧海

BW Query Performance Question:1. What kind of tools are available to monitor the overall Query Performance? Answers: o BW Statistics o BW Workload Analysis in ST03N (Use Export Mo...

Vue-pdf实现在线预览PDF文件

前言 在大多数项目中都会遇到在线预览PDF文件,项目使用的是element ui,使用vue-pdf实现。 安装依赖 npm install --save vue-pdf 相关参数 参数介绍: url :pdf 文件的路径,可以是本地路径,也可以是在线路径。 page: 当前显示的页数,比如第一页page=1 rotate : 旋转角度,比如0就是不旋...

fio硬盘压力测试

fio测试工具支持同步(pread/pwrite)和异步(libaio)FIO是测试IOPS的非常好的工具,用来对硬件进行压力测试和验证,支持13种不同的I/O引擎,包括:sync,mmap, libaio, posixaio, SG v3, splice, null, network, syslet, guasi, solarisaio 等等。  ...

深入理解PHP内核(十四)类的成员变量及方法

原文链接:http://www.orlion.ga/1237/ 类的成员变量在PHP中本质是一个变量,只是这些变量都归属于某个类,并且给这些变量是有访问控制的。 类的成员方法在PHP中本质是一个函数,只是这个函数以类的方法存在,他可能是一个类方法也可能是一个实例方法,并且在这些方法都加上了类的访问控制。类的成员方法是现实世界实体行为的抽象,可以用来实现类的...