runtime 字典转模型,主要是利用runtime的class_copyIvarList方法来获取到类中的所有的成员变量,字典转模型的情况有以下几种情况:
1、json对象中包含对象,这种情况下,如果model定义的属性名和json中对象的参数一致,则不需要做多余的处理,否则要对model中定义的属性名进行指定,已和json数据中的参数一致
2、json对象中包含数组,数组里面包含其他对象;这种情况下,要指定数组里面的对象对应的model模型,类似于YYModel里面的modelContainerPropertyGenericClass方法
例如:
图一 图二例如图一和图二,图一中定义的birthday和图二中的birth是表达一个意思,但是名称不一致,这时就需要将birthday指定成birth
图一定义了一个User属性对象user,这个user和图二的user是一致的,所以即使是对象,也不需要做其他操作
其余注意的地方会在具体的代码中实现出来
// 创建当前类的实例变量
idobjc = [[selfalloc]init];
ididself =self;
unsignedintcount;
// 获取类中所有的属性变量
Ivar* ivarList =class_copyIvarList(self, &count);
// 遍历所有的属性变量
for(inti =0; i < count; i ++) {
// 根据下标获取成员变量
Ivarivar = ivarList[i];
// 获取成员变量名称
NSString * name = [NSString stringWithUTF8String:ivar_getName(ivar)];
// 获取当前的成员变量的类型
NSString * ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
// 对类型type进行处理
ivarType = [ivarTyp estringByReplacingOccurrencesOfString:@"\"" withString:@""];
ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""];
// 处理获取到的变量名——>对获取的name进行截取(name第一位为_)
NSString * key = [name substringFromIndex:1];
// 当字典中的字段和定义属性名不一致的时候,需要对key进行转换,以取得字典中的数据
ididkey = [idself modelCustomPropertyMapper][key];
if(idkey ==nil) {
idkey = key;
}
// 根据key值获取字典中对应的value
id value = dict[idkey];
if(value) {
[objc setValue:value forKey:key];
}}
上述代码中最主要的几点就是runtime里面的几个主要的方法来实现:
1、class_copyIvarList方法,这个方法有两个参数,一个是Class参数,传入的是想获取的model类,另外一个为unsigned int类型,会返回当前类所有的属性变量的个数
2、ivar_getName 这个是获取属性变量名的名称,例如_user
3、ivar_getTypeEncoding 这个方法是获取当前属性名的类型,返回的是:@"\User\"
针对json中的字段和定义的属性不一致的时候,这时就需要指定属性名为json中的字段
图三modelCustomPropertyMapper方法的实现是返回一个字典,字典类似于@{@"birthday":@"birth"},其中birthday是自己定义的属性,birth是json中对应的字段,指定birthday为birth后,则可以在json中获取到对应的数据
二、下面是针对model对象中包含model对象
// 判断当前的value是不是字典
if([value isKindOfClass:[NSDictionary class]] && ![ivarType
hasPrefix:@"NS"]) {
// 获取type的类型
ClassmethodClass =NSClassFromString(ivarType);
// 如果typeClass存在,则
if(methodClass) {
value = [methodClass modelWithDict:value];
}
}
上述代码会获取到当前model对应的类型,如果当前这个model来存在,则进行赋值
三、model对象中包含数组,这个时候就需要指定数组中对应model模型,例如:Person对象中,定义一个users数组,users数组里面包含的对象类型是User这个时候需要在方法arrayContainModelClass中指定:
图四这个处理好之后,就可以处理这种情况了:
// 判断当前的value 是不是数组
if ([value isKindOfClass:[NSArray class]]) {
// 获取到数组value的type
NSString*type = [idselfarrayContainModelClass][key];
// 生成模型
ClassmethodClass =NSClassFromString(type);
NSMutableArray * mulary= [NSMutableArray array];
// 遍历字典数组,生成模型数组
for(NSDictionary* dic in value) {
// 字典转模型
idmodel = [methodClass modelWithDict:dic];
[mulary addObject:model];
}
value = mulary;
}
上述代码理解起来不难,主要是遍历数组,然后保存到value中,赋值
网友评论