我们可以利用KVC来实现字典转模型的问题,但是KVC的使用是有条件的,由于KVC会将字典所有的键值对(key-value)赋值给模型对应的属性,只有当字典的键值对个数和模型的属性个数相等,并且属性名必须和字典的键值对一样时,才可以使用KVC.
必须注意的是,模型中的属性和字典中的属性必须一一对应.
字典转模型的基本步骤:
plist文件的基本结构:
@[
@{name: age: idNumber: },
@{name: age: idNumber: }
……
]
(1)自定义一个模型People类,继承于NSObject
(2)在People.h
中声明与字典对应的属性 以及一个实例方法和一个类方法
@property (nonatomic, copy)NSString * name;
@property (nonatomic, assign)NSNumber * age;
@property (nonatomic, assign)NSNumber * idNumber;
- (instancetype)initWithDictionary:(NSDictionary *)dict;
(重写init方法)
+ (instancetype)peopleWithDictionary:(NSDictionary *)dict;
(注意这里的类方法名的第一个单词和模型的类名一致)
(3)在People.m
中 实现这两个方法
- (instancetype)initWithDictionary:(NSDictionary *)dict{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
+ (instancetype)peopleWithDictionary:(NSDictionary *)dict{
return [[self alloc] initWithDictionary:dict];
}
这里 [self setValuesForKeysWithDictionary:dict];
是用KVC方法来实现的, 相当于用字典中的属性一一赋值给model的对应属性: self.name = dict[@"name"]; self.age = dict[@"age"]; self.idNumber = dict[@"idNumber"];
将模型存入数组中:
在ViewController.m
中声明一个属性数组来存放模型数据
@property (nonatomic, strong)NSArray * peoples;
并实现peoples的getter方法来懒加载数据
#pragma mark - 懒加载数据
- (NSArray *) peoples{
if (_peoples == nil) {
//加载plist,将plist中存储的字典数据放在数组dictArray中
NSString * path = [[NSBundle mainBundle] pathForResource:@"dictToModel.plist" ofType:nil];
NSArray * dictArray = [NSArray arrayWithContentsOfFile:path];
//创建一个可变数组arrayModels来存放模型数据
NSMutableArray * arrayModels = [NSMutableArray array];
//用自定义的模型类型的对象model来接收数组dictArray中的元素, 并添加到arrayModels中
for (NSDictionary * dict in dictArray) {
People * model =[People peopleWithDictionary:dict];
[arrayModels addObject:model];
}
//将arrayModels赋值给_peoples
_peoples = arrayModels;
}
return _peoples;
}
至此字典中的所有数据都存放在_peoples数组中. 需要使用时 ,创建一个模型类型对象 ,将_peoples中对应的数据取出赋值给该对象
模型嵌套模型,不能直接使用KVC 需要通过把字典转模型的代码封装到Group模型中
plist文件的基本结构:
@[
@{
cars:@[@{icon: name: },@{icon: name: },@{icon: name: },……]
title:A
},
@{
cars:@[@{icon: name: },@{icon: name: },@{icon: name: },……]
title:B
}
……
]
首先, 根据car 的数据结构
@[
@{icon: name: },
@{icon: name: },
@{icon: name: }
……
]
创建一个Car
模型类,基本方法步骤和上面的people模型类似,属性为icon, name ,2个方法为
- (instancetype)initWithDictionary:(NSDictionary *)dict{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
+ (instancetype)carWithDictionary:(NSDictionary *)dict{
return [[self alloc] initWithDictionary:dict];
}
然后, 把plist文件的结构看成是
@[
@{
cars: title:
},
@{
cars: title:
}
……
]
创建一个Group
模型类, 基本方法步骤和上面的people模型类似,属性为cars, title , 2个方法为
- (instancetype)initWithDictionary:(NSDictionary *)dict{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
//当有模型嵌套时,需要手动将字典转换成模型
NSMutableArray * arrayModels = [NSMutableArray array];
for (NSDictionary * item_dict in dict[@"cars"]) {
Car * model =[Car carWithDictionary:item_dict];
[arrayModels addObject:model];
}
self.cars = arrayModels;
}
return self;
}
+ (instancetype)groupWithDictionary:(NSDictionary *)dict{
return [[self alloc] initWithDictionary:dict];
}
最后在ViewController
中 通过模型Group来获得字典中的数据,方法和上面的peoples类似.