菜鸟进化史之RunTime实战字典转模型
![](https://img.haomeiwen.com/i671504/5614fd6b37bf9245.jpg)
很久没更新文章了,由于最近公司项目比较赶,所以.......
下面可以看到一个菜鸟的进化史哦。赶紧围观吧。😄
字典转模型在我还是菜鸟的时候,说实话,老老实实在模型里面写的如下代码
1.手动解析
//手动解析
- (instancetype)initWithDic
{
self = [super init];
if (self) {
xxx = dic[@"xxx"];
...
}
return self;
}
2.KVC解析
//kvc解析
- (instancetype)initWithDic
{
self = [super init];
if (self) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
3.第三方框架
是不是很熟悉?我想每个人从开始接触iOS开发到现在都会有一个进化的过程。就这样写了很久直到我走出那家公司,去其他公司面试,被虐的体无完肤。各种炫酷装逼底层层出不穷,面试是一种成长的机会,我是这么认为的。只有当自己看到了差距看到了自己的不足时,为了生存,才会逼自己一把。让自己变的更加的优秀。上面是自己的一点感悟,希望对读者有所帮助。下面我们进入正题。
一般的解析我个人是用KVC,有时候也会用一些第三方的框架,MJ的MJExtension
、JsonModel
等。听说最近面试对于RunTime
问的比较的火,说实话,我对于底层的东西学的很烂,因为实际应用当中很少用到,学着学着过断时间也会忘记。网上的资料也很多,我也来凑下热闹😄下面是我学习RunTime
时的一点实战性的东西。
1.首先创建一个继承NSObject的分类,名字叫DicToModel
2.增加一个方法用于字典转模型,方法名如下:
+ (instancetype)createModelWithDict:(NSDictionary *)dict;
3.导入runtime所需的头文件#import <objc/message.h>
4.接下来我们将实现我们在.h文件里面的方法
+ (instancetype)createModelWithDict:(NSDictionary *)dict{
// 1.创建对应类的对象
id model = [[self alloc] init];
// runtime:遍历模型中所有成员属性,去字典中查找
// 属性定义在哪,定义在类,类里面有个属性列表(数组)
// 遍历模型所有成员属性
// ivar:成员属性
// class_copyIvarList:把成员属性列表复制一份给你
// Ivar *:指向Ivar指针
// Ivar *:指向一个成员变量数组
// class:获取哪个类的成员属性列表
// count:成员属性总数
unsigned int count = 0;
Ivar *ivarList = class_copyIvarList([self class], &count);
for (int i = 0 ; i < count; i++) {
// 获取成员属性
Ivar ivar = ivarList[i];
// 获取成员名
NSString *propertyName = [NSString stringWithUTF8String:ivar_getName(ivar)];
// 获取key
NSString *key = [propertyName substringFromIndex:1];
// user value:字典
// 获取字典的value
id value = dict[key];
// 给模型的属性赋值
// value:字典的值
// key:属性名
// 成员属性类型
NSString *propertyType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
// 二级转换
// 值是字典,成员属性的类型不是字典,才需要转换成模型
if ([value isKindOfClass:[NSDictionary class]] && ![propertyType containsString:@"NSDictionary"]) { // 需要字典转换成模型
// @"@\"xxxx\"" 截取类名字符串
NSRange range = [propertyType rangeOfString:@"\""];
propertyType = [propertyType substringFromIndex:range.location + range.length];
// xxxx\"";
range = [propertyType rangeOfString:@"\""];
propertyType = [propertyType substringToIndex:range.location];
// 获取需要转换类的类对象
Class modelClass = NSClassFromString(propertyType);
if (modelClass) {
value = [modelClass createModelWithDict:value];
}
}
if (value) {// KVC赋值:不能传空
[model setValue:value forKey:key];
}
}
return model;
}
以上代码实现了2层字典转模型,一般情况都没什么问题。如需增加其他的情况只需增加value isKindOfClass
判断做一些处理即可,具体详细的请看代码注释哦!下面我们来看看怎么调用吧!代码如下
- (void)viewDidLoad {
[super viewDidLoad];
// 解析Plist
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"status.plist" ofType:nil];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath];
NSArray *dictArr = dict[@"statuses"];
NSMutableArray *statusesData = [NSMutableArray array];
// 遍历字典数组
for (NSDictionary *dict in dictArr) {
//传字典给我们写的分类返回一个status的模型
Status *status = [Status createModelWithDict:dict];
[statusesData addObject:status];
}
NSLog(@"%@",statusesData);
}
欢迎点喜欢
技术交流群:534926022(免费) 511040024(0.8/人付费)
推荐一款学习iOS开发的app_____|______| | 传送门
版权归©Bison所有 如需转载请保留原文超链接地址!否则后果自负!