iOS支持KVC,所以字典转模型变得超级简单。
我们希望我们写的字典转模型是通用的,这样我就想到用Category,加到Object里面。
然后创建一个Category
@interface NSObject (gh_dict)
//添加两个方法
//第一个方法,是一个类方法,可以通过字典转换成对象
+(instancetype)gh_objWithDict:(NSDictionary*)dict;
//第二个方法,当字典的key与属性不匹配的时候,进行匹配
-(NSDictionary*)gh_exchangeDict;
@end
接下来要写实现部分了
@implementation NSObject (gh_dict)
+(instancetype)gh_objWithDict:(NSDictionary*)dict
{
id obj = [self new];
/*
通常我我们使用的方法是setValueForKey,但是当我们进行批量操作的时候
系统为我们实现了将整个字典,通过KVC赋值到对象,
不过当我们的字典的key在属性里面没有的时候,系统会抛一个UndefinedKey的异常,导致程序崩溃
*/
[obj setValuesForKeysWithDictionary:dict];
return obj;
}
/*
由于上面讲的,字典的key在属性里面没有的时候,程序崩溃,所以我们可以通过重写下面方法来避免崩溃
(因为系统的默认实现就是抛异常,所以重写该方法就不会崩溃,这很好理解)
*/
-(void)setValue:(id)value forUndefinedKey:(NSString *)key
{
//我们通过gh_exchangeDict方法,给调用方一次匹配的机会,比如我们的字典和属性都有,但是不匹配,这时候我们需要存储一个对应关系
//默认的实现就是return nil
NSDictionary* exchangeDict = [self gh_exchangeDict];
if (exchangeDict) {
//当匹配字典存在的时候,通过字典key得到属性名
NSString* newKey = exchangeDict[key];
//kvc赋值
[self setValue:value forKey:newKey];
}
}
-(NSDictionary *)gh_exchangeDict
{
return nil;
}
@end
//创建一个测试的类,学生类,有年龄,性别,名字
@interface Student:NSObject
@property(nonatomic,assign) int age;
@property(nonatomic,copy) NSString* name;
@property(nonatomic,assign) BOOL sex;
@end
@implementation Student
//重写匹配字典
-(NSDictionary*)exchangeDict
{
return @{@"Age":@"age"};
}
@end
client端代码:
//字典
NSDictionary* studentDict = @{@"Age":@(5),@"name":@"张三",@"sex":@(NO),@"other":@"hehe"};
//字典转模型
Student
* st = [Student
gh_objWithDict
:studentDict];
调试过程中,我们发现已经成功的转换了。