很久没更新文章了,由于最近公司项目比较赶,所以……. 下面可以看到一个菜鸟的进化史哦。赶紧围观吧。:smile: 字典转模型在我还是菜鸟的时候,说实话,老老实实在模型里面写的如下代码
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
问的比较的火,说实话,我对于底层的东西学的很烂,因为实际应用当中很少用到,学着学着过断时间也会忘记。网上的资料也很多,我也来凑下热闹:smile:下面是我学习 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); }
学习iOS开发的app上线啦,点此来围观吧
更多经验请点击
好文推荐: 分分钟解决iOS开发中App启动动画广告的功能