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;

}

猜你喜欢

转载自www.cnblogs.com/diweinan/p/9717676.html