iOS-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.动态的遍历一个类的所有成员变量,用于字典转模型,归档解档操作:

// 利用runtime遍历一个类的全部成员变量
// 1.导入头文件<objc/runtime.h> 
unsigned int count = 0;
// Ivar:表示成员变量类型 
Ivar *ivars = class_copyIvarList([UIPageControl 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);
 }
}

运行结果如下:

这里写图片描述

如果用KVC修改这两个属性有惊喜哦!!!

2.获取一个类的全部属性:

    unsigned int count = 0;
    objc_objectptr_t *properties = class_copyPropertyList([UIPageControl class], &count);
    for (int i = 0; i < count; i ++) {
        objc_objectptr_t property = properties[i];
        const char *name = property_getName(property);
        NSString *key = [NSString stringWithUTF8String:name];
        NSLog(@"%d UIPageControl -> %@",i,key);
    }

应用场景:

一、可以利用遍历类的属性,来快速的进行归档操作

将从网络上下载的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,如果添加程序会崩,用自己的方法替换系统防止系统崩溃.
代码实现如下:

这里写图片描述
这里写图片描述

再次运行刚才的程序:
这里写图片描述

文章借鉴于

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值