runtime 优化归档 ,替换方法

来源:互联网 发布:怪物猎人4g手机数据库 编辑:程序博客网 时间:2024/06/03 07:24
文/Gavin_peng(简书作者)
原文链接:http://www.jianshu.com/p/364eab29f4f5
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

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

运行结果如下:


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


获取一个类的全部属性:


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


结果如下:


输出结果.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

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

    再次运行刚才的程序:

    最终运行结果图.png
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 外阴部长了一个疙瘩有点痒怎么办 小孩打架被另一个小孩家人告怎么办 德保豆浆机有电但不工作怎么办 刚买的笔记本c盘不足怎么办 qq糖粘在喉咙气管里怎么办 穿上旗袍后感觉后腰处不平整怎么办 机打票给客人给错联怎么办?急 ps修证件照感觉不太立体怎么办 手机百度上下载的文档打不开怎么办 5岁宝宝乘飞机没带证件怎么办 网上订飞机票忘记订儿童票了怎么办 两岁宝宝对牛奶鸡蛋过敏了怎么办 两岁宝宝坐不住好跑怎么办 宝宝两岁多了不愿意坐小马桶怎么办 坐火车小孩拉屎在被子上怎么办 川航飞机票名字错了一个字怎么办 胜战本领怎么看走向战场怎么办 数数字油画你的颜料干了怎么办? 数字油画涂颜料涂错了怎么办 绝地求生模拟器注册已达上限怎么办 孕妇把番茄和虾一起吃了怎么办 4岁宝贝吃了玩具小电池怎么办 微信使用零钱需完善实名信息怎么办 两岁宝宝刷牙不会吐水怎么办 孩子牙龈上长了小牙怎么办 供暖公司未供暖却收取供暖费怎么办 两岁宝宝认知和语言能力低怎么办 蜡笔同步被对方发现删掉的怎么办 微信时间和手机时间不同步怎么办 孩子们家乡爱画美丽的也自己怎么办 娃把豆豆弄进鼻孔了怎么办 20岁了不知道自己该干什么怎么办 遇到一个新手买家恶意拍下怎么办 淘宝卖螃蟹有什么要求美工怎么办 淘宝衣服吊牌剪了想退货怎么办修 用图片在淘宝搜衣服搜不到怎么办 汽车黑塑料水砂纸磨的不平怎么办 sat报名要你填10位电话怎么办 手绘板连接电脑绘画有点迟钝怎么办 走路不小心滑了一下特尴尬怎么办 小孩子头撞了头发长不出来怎么办