Skip to content

如何运用 Runtime 字典转模型? #56

@tbfungeek

Description

@tbfungeek

这部分的思路就是通过class_copyIvarList获取Model的各个属性,然后去掉属性名字下的下划线,作为查询字典的key。取出值通过KVC设置到model,
这里有两个比较关键的问题,当model属性为字典或者自定义类型的时候需要怎么处理,当model属性为数组的时候怎么处理。代码如下:

+ (instancetype)idl_modelWithDic:(NSDictionary *)dictionary {

    if(!dictionary || ![dictionary count]) return nil;

    id objc = [[self alloc] init];

    unsigned int outCount = 0;
    //没有参数的情况
    Ivar *varList = class_copyIvarList([self class], &outCount);
    if(!outCount) {
        free(varList);
        return objc;
    }

    for (unsigned int index = 0; index < outCount; index++) {

        //获取到属性名称
        NSString *varName = [NSString stringWithUTF8String:ivar_getName(varList[index])];
        if(!varName || ![varName length]) continue;
        //去掉下划线_
        varName = [varName substringFromIndex:1];
        //去掉@ 和 “ 之后的实例变量类型 获取到的时候类型为@"NSString"这种
        NSString *varType = [NSString stringWithUTF8String:ivar_getTypeEncoding(varList[index])];
        varType = [varType stringByReplacingOccurrencesOfString:@"\"" withString:@""];
        varType = [varType stringByReplacingOccurrencesOfString:@"@" withString:@""];

        //取得变量值
        id varValue = dictionary[varName];

        //自定义类型处理
        if([varValue isKindOfClass:[NSDictionary class]] || ![varType hasPrefix:@"NS"]) {
            //拿到自定义类型 递归生成 自定义的类型属性
            Class modelClass = NSClassFromString(varType);
            if(modelClass) {
                varValue = [modelClass idl_modelWithDic:varValue];
            }
        }

        //实例变量为数组类型
        if([varValue isKindOfClass:[NSArray class]] || [varValue isKindOfClass:[NSMutableArray class]]) {
            //获取映射的模型类型
            if([self respondsToSelector:@selector(arrayElementModelTypeMap)]) {
                //拿到元素类型
                NSDictionary *arrayElementModelTypeMap = [self performSelector:@selector(arrayElementModelTypeMap)];
                Class elementModelType = arrayElementModelTypeMap[varName];

                NSMutableArray *array = [NSMutableArray new];
                for (NSDictionary *dict in varValue/*这个为字典数组*/) {
                    id elementValue = [elementModelType idl_modelWithDic:dict];
                    [array addObject:elementValue];
                }
                varValue = array;
            }
        }

        //赋值
        if(varValue) {
            [objc setValue:varValue forKey:varName];
        }
    }
    free(varList);
    return objc;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions