老样子直接上干货!
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;
}