一、Objc/runtime 是一组C的API 作用:
1、程序运行时候,动态创建类
2、程序运行时候,动态创建类中方法和属性
3、遍历类中所有成员变量
二、废话不多说,直接上代码。
1、使用runtime 实现消息机制
(1)假设有个类Person 声明一个方法 eat
普通发送一个消息:Person *person = [[Person alloc] init]; [p eat];或者 [p performSelector:@selector(eat)];
runtime发送一个消息:objc_msgSend(p, @selector(eat)); 补充一下 oc下面每一个方法都有 SEL 和IMP 组成
SEL是方法编号,IMP是方法实现。
(2)设置连Person *person = [[Person alloc] init]; 都可以用runtime实现
Person *p = objc_msgSend(objc_getClass("Person"), sel_registerName("alloc"));
p = objc_msgSend(p, @selector(init));
objc_msgSend(p, @selector(eat));
(3)新建一个命令行工程,对main方法进行转objc代码,命令行:clang -rewrite-objc main.m 就可以查看
经过验证,和我们写的代码 是一样的。
2、runtime实际应用 ---使用runtime实现序列化。
第一步:实现一个Person类的归档解档,一般实现:
vc实现存、取操作
新建Person类 遵从NSCoding协议, 假设目前2个属性 name 和age
第二步 : 思考一个问题,一般来说我们的model模型 属性非常多,有时候会有几十个,难道每一次都要重复写encode 和 decode 代码吗?解决方案就是:使用runtime获取成员变量的列表 从而实现一劳永逸的序列化。
解释一下:class_copyIvarList 可以用来成员变量的列表,同时count经过这个方法之后,变成成员变量的个数,返回值就是Ivar的结构体,每一个Ivar对象 就可以通过ivar_getName 来获取属性名字,从而通过kvc 来获取value。
第三步: class_copyIvarList 是C方法,一般C里面 copy、new、create 都会分配内存,所以最后用完 要释放 堆内存中的Ivar * 也就是free(ivars)