美文网首页
iOS开发:runtime实现字典转模型

iOS开发:runtime实现字典转模型

作者: yangfei02821 | 来源:发表于2020-07-03 19:19 被阅读0次

    实现思路:

    遍历模型中所有属性,根据模型的属性名去字典中查找key,取出对应的的值,给模型的属性赋值

    使用到的runtime函数:

    拷贝实例变量列表(最后需要调用free释放)

    • Ivar *class_copyIvarList(Class cls, unsigned int *outCount)

    获取成员变量的相关信息

    • const char *ivar_getName(Ivar v)
    • const char *ivar_getTypeEncoding(Ivar v)

    1、首先获取类中所有成员变量,然后遍历取出每一个成员变量,获取变量名,即为字典中的key,从字典中取出value,然后进行赋值。
    2、如果value是字典类型,就取出成员变量的属性类型,根据反射机制,生成类对象,然后对这个类对象进行字典赋值,遵循一级转换。
    3、如果value是数组类型,判断对应类有没有实现字典数组转模型的协议,从中能够获取到字典数组中字典对应的模型,遍历字典数组,根据二级转换,生成模型数组。

    一级转换

        id objc = [[self alloc] init];
        
        unsigned int count;
        
        // 获取类中的所有成员属性
        Ivar *ivarList = class_copyIvarList(self, &count);
        
        for (int i = 0; i < count; i++) {
            Ivar ivar = ivarList[i];
            
            // 获取成员属性名
            NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
            
            // 处理成员属性名->字典中的key
            // 从第一个角标开始截取
            NSString *key = [name substringFromIndex:1];
            
            // 根据成员属性名去字典中查找对应的value
            id value = dict[key];
    

    二级转换

        if ([value isKindOfClass:[NSDictionary class]]) {
                // 获取成员属性类型
                NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
                // 生成的是这种@"@\"User\"" 类型 -》 @"User"  在OC字符串中 \" -> ",\是转义的意思,不占用字符
                // 裁剪类型字符串
                NSRange range = [type rangeOfString:@"\""];
                
                type = [type substringFromIndex:range.location + range.length];
                range = [type rangeOfString:@"\""];
                // 裁剪到哪个角标,不包括当前角标
                type = [type substringToIndex:range.location];
                // 根据字符串类名生成类对象
                Class modelClass = NSClassFromString(type); 
                if (modelClass) {
                    value  =  [modelClass modelWithDict:value];
                }
            }
    

    三级转换

            if ([value isKindOfClass:[NSArray class]])
            {
                // 判断对应类有没有实现字典数组转模型数组的协议
                if ([self respondsToSelector:@selector(arrayContainModelClass)]) {
                    
                    // 转换成id类型,就能调用任何对象的方法
                    id idSelf = self;
                    // 获取数组中字典对应的模型
                    NSString *type =  [idSelf arrayContainModelClass][key];
                    // 生成模型
                    Class classModel = NSClassFromString(type);
                    NSMutableArray *arrM = [NSMutableArray array];
                    // 遍历字典数组,生成模型数组
                    for (NSDictionary *dict in value) {
                        // 字典转模型
                        id model =  [classModel modelWithDict:dict];
                        [arrM addObject:model];
                    }
                    // 把模型数组赋值给value
                    value = arrM;
                }
            }
    

    借鉴:
    使用RunTime实现字典转模型

    相关文章

      网友评论

          本文标题:iOS开发:runtime实现字典转模型

          本文链接:https://www.haomeiwen.com/subject/zwgsqktx.html