字典转模型一般都两种方式,1、图方便用的mj框架;2、自己在模型中写类方法,用KVC实现。
换换口味,尝试下runtime,如果想仅仅实现自己需要的功能其实很简单,就那几个C语言函数
实现两级嵌套字典的转换:
#import <objc/message.h>
@implementation NSObject (Model)
+ (instancetype)modelWithDict:(NSDictionary *)dict{
// 1.创建对应类的对象
id objc = [[self alloc] init];
// runtime:遍历模型中所有成员属性,去字典中查找
// 属性定义在哪,定义在类,类里面有个属性列表(数组)
unsigned int count = 0;
Ivar *ivarList = class_copyIvarList(self, &count);
for (int i = 0 ; i < count; i++) {
// 获取成员属性
Ivar ivar = ivarList[i];
// 获取成员名
NSString *propertyName = [NSString stringWithUTF8String:ivar_getName(ivar)];
// 获取key(默认是以下划线开头的变量)
NSString *key = [propertyName substringFromIndex:1];
// 成员属性类型
NSString *propertyType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
// user:NSDictionary
// 二级转换
// 值是字典,成员属性的类型不是字典,才需要转换成模型
if ([value isKindOfClass:[NSDictionary class]] && ![propertyType containsString:@"NS"]) { // 需要字典转换成模型
// 转换成哪个类型(转移符)
NSRange range = [propertyType rangeOfString:@"\""];
propertyType = [propertyType substringFromIndex:range.location + range.length];
range = [propertyType rangeOfString:@"\""];
propertyType = [propertyType substringToIndex:range.location];
// 获取需要转换类的类对象
Class modelClass = NSClassFromString(propertyType);
if (modelClass) {
value = [modelClass modelWithDict:value];
}
}
if (value) {
// KVC赋值:不能传空
[objc setValue:value forKey:key];
}
}
return objc;
}
主要是 获取对象的属性列表: class_copyIvarList ,C语言字符串转OC: ivar_getName,再通过操作字符串,最后赋值。