转载 --ios 模型-setValuesForKeysWithDictionary

时间:2022-01-10 04:56:45

应用场景:app请求后端数据,返回的数据是JSON形式,如:

  1. {
  2. "is_favor" = 0;
  3. "is_follow" = 0;
  4. "is_praise" = 0;
  5. "is_self" = 0;
  6. }

我经常new一个接受该组数据的class,然后用对象的setValuesForKeysWithDictionary方法对每个字段自动进行赋值。

  1. HSTopicModel *model = [HSTopicModel new];
  2. [model setValuesForKeysWithDictionary:responseJSON];

只要后端JSON数据的每个字段和前端定义的model中的每个字段命名一致,setValuesForKeysWithDictionary就可以帮助我们一一对应的把model的每个字段赋好值。如果有字段命名不一致的情况,我们可以在model的.m文件中实现一个方法,- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key; 它可以让我们把命名不一致的字段手动赋值。

  1. - (void)setValue:(id)value forUndefinedKey:(NSString *)key {
  2. if (key) {
  3. if([key isEqualToString:@"id"]) {
  4. _uid = [self numberToString:value];
  5. } else if ([key isEqualToString:@"is_follow"]) {
  6. _isFollow = (1 == [self numberToInt:value]) ? YES : NO;
  7. } else if ([key isEqualToString:@"is_editer"]) {
  8. _isEditer = (1 == [self numberToInt:value]) ? YES : NO;
  9. } else if ([key isEqualToString:@"constelltion"]) {
  10. _constellation = [self numberToString:value];
  11. } else if ([key isEqualToString:@"status"]) {
  12. _isBlocked = (1 == [self numberToInt:value]) ? YES : NO;
  13. } else if ([key isEqualToString:@"nospeak"]) {
  14. _isBanned = (1 == [self numberToInt:value]) ? YES : NO;
  15. }
  16. }
  17. }

另外还有一个方法,与这个方法功能相反 - (void)setValue:(nullable id)value forKey:(NSString *)key; 这是让我们手动给命名一致的字段赋值的方法,这两个方法如果同时实现,那么只会运行- (void)setValue:(nullable id)value forKey:(NSString *)key; 这个方法。

这种方式用了很久,不过最近出现了一次灵异现象。后端数据的字段名为"nospeak",前端定义的为"isNoSpeak",在模拟器iPhone6(9.0)上运行正常,但是到了模拟器iPhone5s(9.0)上一跑到给这个字段赋值时就crash,百思不得姐,于是将字段名随便更换了一个,结果crash现象消失了,再换回"isNoSpeak",又开始crash。最终没有找到问题的根因,并且消耗了很多时间定位问题。

之后,我决定换一种赋值的方法,即在model的.m文件中实现

- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *,id> *)keyedValues; 方法。虽然这个方法需要对每个字段手动赋值,但是可以方便我们对每个字段进行类型判断等校验,一旦出现问题,可以很快定位。

  1. - (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *,id> *)keyedValues
  2. {
  3. if (keyedValues) {
  4. for (NSString *key in [keyedValues keyEnumerator]) {
  5. if([key isEqualToString:@"id"]) {
  6. _tid = [self numberToString:[keyedValues objectForKey:key]];
  7. } else if ([key isEqualToString:@"score"]) {
  8. _score = [self numberToString:[keyedValues objectForKey:key]];
  9. } else if ([key isEqualToString:@"title"]) {
  10. _title = [self numberToString:[keyedValues objectForKey:key]];
  11. }
  12. }
  13. }
  14. }

原文:http://blog.csdn.net/worldzhy/article/details/49982179#