iOS 字典转模型runtime实现

老样子直接上干货!

runtime获取模型类的所有成员变量的方法 

1. class_copyIvarList(Class _Nullable cls:表示获取哪个类中的成员变量, unsigned int * _Nullable outCount:表示这个类有多少成员变量,传入一个Int变量地址,会自动给这个变量赋值);

2. 获取成员变量名字 ivar_getName(@"");

3. 生成模型NSClassFromString(@"");

+ (instancetype)modelWithObject:(NSDictionary *)dict {

  // 首先创建目标类的对象

  id objc = [[self alloc] init];

  // 获取所有的成员变量, 并且获取数量

unsigned int count = 0;

Ivar *ivarList = class_copyIvarList(self, &count);

  // 遍历所有成员变量

  for (int i = 0; i < count; i++) {

    // 从数组中获取成员变量, (注意: Ivar成员变量是 "_"开头的)

    Ivar ivar = ivarList[i];

// 获取成员变量名字 

NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)]; 

// 获取成员变量类型 

NSString *ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)]; 

    // 处理好成员变量的类型字符 去掉特殊符号

ivarType = [ivarType stringByReplacingOccurrencesOfString:@"\"" withString:@""];

ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""];

    // 处理成员变量名->字典中的key(去掉 _ ,从第一个角标开始截取)

NSString *key = [ivarName substringFromIndex:1];

    // 根据成员属性名去字典中查找对应的value

id value = dict[key];

    // 判断值是否是数组

if ([value isKindOfClass:[NSArray class]]) {

      // 判断对应类有没有实现字典数组转模型数组的协议, 协议名称自己可以随便定义, 返回的字典里key对应的类的名称字符串

      // arrayContainModelClass 提供一个协议,只要遵守这个协议的类,都能把数组中的字典转模型

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 modelWithDict3:dict];

           [arrM addObject:model];

         }

 // 把模型数组赋值给value 

        value = arrM;

      }

    }

// 如果模型属性数量大于字典键值对数理,模型属性会被赋值为nil,而报错 

if (value) { 

// 给模型中属性赋值

     [objc setValue:value forKey:key];

     }

  }

return objc;

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。