应用场景:app请求后端数据,返回的数据是JSON形式,如:
{
"is_favor" = 0;
"is_follow" = 0;
"is_praise" = 0;
"is_self" = 0;
}
我经常new一个接受该组数据的class,然后用对象的setValuesForKeysWithDictionary方法对每个字段自动进行赋值。
HSTopicModel *model = [HSTopicModel new];
[model setValuesForKeysWithDictionary:responseJSON];
只要后端JSON数据的每个字段和前端定义的model中的每个字段命名一致, setValuesForKeysWithDictionary就可以帮助我们一一对应的把model的每个字段赋好值。如果有字段命名不一致的情况,我们可以在model的.m文件中实现一个方法, - ( void )setValue:( nullable id )value forUndefinedKey:( NSString *)key; 它可以让我们把命名不一致的字段手动赋值。
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
if (key) {
if([key isEqualToString:@"id"]) {
_uid = [self numberToString:value];
} else if ([key isEqualToString:@"is_follow"]) {
_isFollow = (1 == [self numberToInt:value]) ? YES : NO;
} else if ([key isEqualToString:@"is_editer"]) {
_isEditer = (1 == [self numberToInt:value]) ? YES : NO;
} else if ([key isEqualToString:@"constelltion"]) {
_constellation = [self numberToString:value];
} else if ([key isEqualToString:@"status"]) {
_isBlocked = (1 == [self numberToInt:value]) ? YES : NO;
} else if ([key isEqualToString:@"nospeak"]) {
_isBanned = (1 == [self numberToInt:value]) ? YES : NO;
}
}
}
这种方式用了很久,不过最近出现了一次灵异现象。后端数据的字段名为"nospeak",前端定义的为"isNoSpeak",在模拟器iPhone6(9.0)上运行正常,但是到了模拟器iPhone5s(9.0)上一跑到给这个字段赋值时就crash,百思不得姐,于是将字段名随便更换了一个,结果crash现象消失了,再换回"isNoSpeak",又开始crash。最终没有找到问题的根因,并且消耗了很多时间定位问题。
之后,我决定换一种赋值的方法,即在model的.m文件中实现
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *,id> *)keyedValues; 方法。虽然这个方法需要对每个字段手动赋值,但是可以方便我们对每个字段进行类型判断等校验,一旦出现问题,可以很快定位。
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *,id> *)keyedValues
{
if (keyedValues) {
for (NSString *key in [keyedValues keyEnumerator]) {
if([key isEqualToString:@"id"]) {
_tid = [self numberToString:[keyedValues objectForKey:key]];
} else if ([key isEqualToString:@"score"]) {
_score = [self numberToString:[keyedValues objectForKey:key]];
} else if ([key isEqualToString:@"title"]) {
_title = [self numberToString:[keyedValues objectForKey:key]];
}
}
}
}