由于OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法。利用runtime机制让我们可以在程序运行时动态修改类、对象中的所有属性、方法。
下面就介绍运行时一种很简单的使用方式,将字典对象转为模型。当然,你可能会问,我用KVO直接调用 setValuesForKeysWithDictionary:方法,传入一个字典一样可以快速将字典转模型啊,但是这种方法有它的弊端,只有遍历某个模型中所有的成员变量,然后通过成员变量从字典中取出对应的值并赋值最为稳妥,否则,当模型中的属性数量与字典中的key的数量不一样时,就会报错。而且,由于runtime是更底层的语言,我们编写的OC代码在运行时,编译器内部会先转为C和C++的代码,然后再执行,因而运用runtime机制,程序的性能也会更好。说了这么多,下面就初步认识一下runtime的强大。
首先,我们定义一个类
复制代码
@interface Person : NSObject{
CGFloat height;
}
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSNumber *age;
@property (nonatomic, assign) int no;
@end
复制代码
然后,我们在其它文件中使用这个类,注意在使用之前,要包含 #import <objc/message.h>
下面通过一小段代码来获取到上面这个类中所有的成员变量
复制代码
unsigned int outCount = 0;
Ivar *vars = class_copyIvarList([Lender class], &outCount); // 获取到所有的成员变量列表
// 遍历所有的成员变量
for (int i = 0; i < outCount; i++) {
Ivar ivar = vars; // 取出第i个位置的成员变量
const char *propertyName = ivar_getName(ivar); // 获取变量名
const char *propertyType = ivar_getTypeEncoding(ivar); // 获取变量编码类型
printf("---%s--%s\n", propertyName, propertyType);
}
复制代码
打印结果:
---height--f
---_name--@"NSString"
---_age--@"NSNumber"
---_no--i
可见,通过上面几句简单的代码就可以获取到某个类中所有变量的名称和类型,然后通过object_setIvar()方法为具体某个对象的某个成员变量赋值。 |