Objective-C 只覆盖非 nil 属性 [英] Objective-C Overwrite only non-nil properties

查看:53
本文介绍了Objective-C 只覆盖非 nil 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个 Car 类,具有以下属性方案:

Let's say I have a class Car, with the following property scheme:

@interface Car : NSObject

@property int carID;
@property Driver *driver;
@property NSString *brandName;
...

@end

现在,我有一个 Car 实例的字典,每当我从我的服务器下载一个新实例时,我都会用 carDictionary[@(newCar.carID)] = newCar; 以保持我的实例更新.唯一的问题是有时我的实例下载时有些属性没有填写.

Now, I have a dictionary of Car instances, and whenever I download a new instance from my server, I overwrite with carDictionary[@(newCar.carID)] = newCar; to keep my instances updated. The only issue is that sometimes my instances are downloaded with some properties not filled out.

当我下载一个新实例时,有没有办法只使用我下载的非 nil 属性进行覆盖,而将 nil 属性单独保留? 显然,我可以手动设置每个属性,但我不想每次添加新属性时都必须更改此设置.

When I download a new instance, is there a way to only overwrite using the non-nil properties I download and leave the nil properties alone? Obviously, I could manually set each property, but I don't want to have to change this every time I add a new property.

推荐答案

假设您通过 Web 服务调用获得了一本字典.现在您想使用该字典来实例化或更新 Car 对象,其中更新不会用字典中的 nil 数据覆盖现有的有效数据.

Let's say you get a dictionary as a result of your web service call. Now you want to use that dictionary to instantiate or update a Car object, where an update does not overwrite existing valid data with nil data from the dictionary.

假设类中的属性名称与字典中的键名称相对应.

Assume the property names in your class correspond to the key names in your dictionary.

这是一种方法:

  1. 从 carDictionary 中获取当前字典的现有 Car 对象:

  1. Get the existing Car object for the current dictionary from the carDictionary:

Car *currentCar = carDictionary[@(newCar.carID)];

如果没有返回汽车,则实例化一辆新汽车:

If no car is returned, instantiate a new one:

  if (currentCar == nil) {
    currentCar = [[Car alloc] init];
   }

  • 将下载的字典中的所有值分配给汽车实例:

  • Assign all the values from your downloaded dictionary to the car instance:

    [currentCar setValuesForKeysWithDictionary:yourDownloadedDictionary];

    该方法会将字典中的键映射到 Car 实例中的键.字典键需要与您的类中的键匹配,通常只使用相同的名称是值得的,这样您就可以使用这种方便的方法.

    That method will map the keys from the dictionary with the keys in your Car instance. The dictionary keys need to match the keys in your class, and often it's worth just using the same names so you get to use this convenient method.

    如果添加到您的 Web 服务字典中的新键与您的类中的键/属性无关,则会引发异常.如果您的 Web 服务开始提供新密钥而某些用户使用您的应用程序版本已过时,这会破坏您的应用程序.为了解决这个问题..

    It will throw an exception if there is a new key added to your web service dictionary that does not correlate to a key/property in your class. This would break your app if your web service started giving out new keys while some users had outdated versions of your app. To solve that..

    覆盖 - (void)setValue:(id)value forUndefinedKey:(NSString *)key; 所以它什么都不做,除了可能注销一个键试图被设置,但你的班级没有实现那个键/属性.

    Override - (void)setValue:(id)value forUndefinedKey:(NSString *)key; so it does nothing, other than perhaps log out the fact that a key was attempted to be set but your class doesn't implement that key/property.

    然后你就会遇到不要设置 nil 值"的问题.你可以告诉你的班级不要用 nil 值覆盖现有的内容...

    Then you have the problem of "Don't set nil values". You can tell your class not to overwrite existing content with nil values by...

    1. 覆盖 -(void)setValue:forKey:

    -(void)setValue:(id)value forKey:(NSString *)key {
       if (value != nil) {
         [super setValue:value forKey:key];
    } else {
             NSLog(@"Not changing %@ because its value is nil.", key);
       }
      }
    

  • 设置类需要做更多的工作,但它为您提供了未来的证明,以便您的 Web 服务扩展其返回的属性集.

    It's a bit more work in setting up the class, but it gives you future proofing for when your web service expands its returned attribute set.

    这篇关于Objective-C 只覆盖非 nil 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆