Objective-C仅覆盖非零属性

时间:2014-12-23 18:06:10

标签: objective-c properties

我们说我有一个班级Car,其中包含以下属性方案:

@interface Car : NSObject

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

@end

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

当我下载一个新实例时,有没有办法只使用我下载的非零属性覆盖并单独保留nil属性?显然,我可以手动设置每个属性,但是我我不希望每次添加新房产时都要更改此设置。

3 个答案:

答案 0 :(得分:2)

在Objective-C中没有内置的方法来执行此操作。也就是说,我认为这就是我接近它的方式。

我首先在Car上添加一个方法,用新信息更新它:

-(void)updateWithNewCarInfo(Car *)newCar

直接的方法是自己手动复制属性。但是如果你想做一些面向未来的工作,你可以使用Objective-C的内省功能来获取你的类的属性列表,并自己迭代它们。 This question对如何做到这一点有一些指示。但是,您需要实现自己的逻辑,以确定在何时覆盖哪些属性。

答案 1 :(得分:2)

由于此地点的carDictionary中已经有一个Car对象,而不是大肆替换它,所以写一个Car方法updateWithValuesFromCar:,然后再接另一辆Car并做你想做的事,然后调用它。

我将从一个属性名称@["carID", "driver", "brandName"](依此类推)开始,然后循环使用键值编码来检查每个传入的属性值,并决定是否替换我自己的相应属性值。 / p>

答案 2 :(得分:1)

我们假设您的网络服务电话会收到字典。现在,您希望使用该字典来实例化或更新Car对象,其中更新不会使用字典中的nil数据覆盖现有的有效数据。

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

这是一种方法:

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

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

  2. 如果没有返回汽车,请实例化一个新车:

      if (currentCar == nil) {
        currentCar = [[Car alloc] init];
       }
    
  3. 将下载词典中的所有值分配给汽车实例:

    [currentCar setValuesForKeysWithDictionary:yourDownloadedDictionary];

    该方法将使用Car实例中的键映射字典中的键。字典键需要与您班级中的键匹配,并且通常值得使用相同的名称,因此您可以使用这种方便的方法。

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

  4. 覆盖- (void)setValue:(id)value forUndefinedKey:(NSString *)key;所以它什么都不做,除了可能会注意到尝试设置密钥但你的类没有实现该密钥/属性的事实。

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

    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);
         }
        }
      
    2. 在设置课程方面还有一些工作要做,但它可以为您的Web服务扩展其返回的属性集提供进一步的证明。