Objective-C仅覆盖非零属性

Objective-C仅覆盖非零属性,objective-c,properties,Objective C,Properties,假设我有一辆等级车,拥有以下财产计划: @interface Car : NSObject @property int carID; @property Driver *driver; @property NSString *brandName; ... @end 现在,我有一个Car实例字典,每当我从服务器下载一个新实例时,我都会用carDictionary[@newCar.carID]=newCar覆盖;使我的实例保持更新。唯一的问题是,有时下载我的实例时没有填写某些属性 当我下载一个

假设我有一辆等级车,拥有以下财产计划:

@interface Car : NSObject

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

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


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

Objective-C中没有内置的方法来实现这一点。也就是说,我认为这就是我将如何处理它

首先,我将在Car上添加一个方法,该方法使用新信息对其进行更新:

-(void)updateWithNewCarInfo(Car *)newCar

简单的方法是自己手动复制属性。但如果您想做一些未来的验证,您可以使用Objective-C的内省功能来获取类上的属性列表,并自己迭代它们。有一些关于如何做到这一点的建议。不过,您需要实现自己的逻辑,以确定何时覆盖哪些属性。

Objective-C中没有内置的方法。也就是说,我认为这就是我将如何处理它

首先,我将在Car上添加一个方法,该方法使用新信息对其进行更新:

-(void)updateWithNewCarInfo(Car *)newCar

简单的方法是自己手动复制属性。但如果您想做一些未来的验证,您可以使用Objective-C的内省功能来获取类上的属性列表,并自己迭代它们。有一些关于如何做到这一点的建议。不过,您需要实现自己的逻辑,以确定何时覆盖哪些属性。

因为此时CardDictionary中已经有一个Car对象,而不是随意替换它,请编写一个Car方法updateWithValuesFromCar:它占用另一辆车并执行您希望执行的操作,并调用该方法


我会从属性名数组@[carID、driver、brandName]等开始,然后循环使用,使用键值编码检查每个传入的属性值,并决定是否替换我自己相应的属性值。

因为此时carDictionary中已经有一个Car对象,而不是随意替换它,编写一个Car方法updateWithValuesFromCar:它占用另一辆车并执行您想要的操作,并调用它


我将从属性名数组@[carID、driver、brandName]开始,然后循环使用,使用键值编码检查每个传入的属性值,并决定是否替换我自己相应的属性值。

假设您在web服务调用后得到一个字典。现在,您希望使用该字典实例化或更新一个Car对象,其中更新不会用字典中的nil数据覆盖现有的有效数据

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

以下是一种方法:

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

Car*currentCar=carDictionary[@newCar.carID]

如果没有归还车辆,请实例化一辆新的:

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

[currentCar setValuesForKeysWithDictionary:yourDownloadedDictionary]

该方法将把字典中的钥匙映射到汽车实例中的钥匙。字典键需要与类中的键相匹配,通常使用相同的名称是值得的,因此可以使用这种方便的方法

如果web服务字典中添加了与类中的键/属性不相关的新键,则会引发异常。如果您的web服务开始发出新密钥,而一些用户的应用程序版本已经过时,那么这将破坏您的应用程序。为了解决这个问题

Override-VOIDESETVALUE:idvalue forUndefinedKey:NSString*键;所以它什么也不做,只是可能会注销一个事实,即试图设置一个键,但您的类没有实现该键/属性

然后你就遇到了不设置零值的问题。您可以告诉您的类不要用零值覆盖现有内容,方法是

覆盖-无效设置值:forKey:


在设置类时需要做更多的工作,但它为您提供了将来web服务扩展其返回属性集时的证明。

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

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

以下是一种方法:

从c语言中获取当前字典的现有Car对象 词典:

Car*currentCar=carDictionary[@newCar.carID]

如果没有归还车辆,请实例化一辆新的:

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

[currentCar setValuesForKeysWithDictionary:yourDownloadedDictionary]

该方法将把字典中的钥匙映射到汽车实例中的钥匙。字典键需要与类中的键相匹配,通常使用相同的名称是值得的,因此可以使用这种方便的方法

如果web服务字典中添加了与类中的键/属性不相关的新键,则会引发异常。如果您的web服务开始发出新密钥,而一些用户的应用程序版本已经过时,那么这将破坏您的应用程序。为了解决这个问题

Override-VOIDESETVALUE:idvalue forUndefinedKey:NSString*键;所以它什么也不做,只是可能会注销一个事实,即试图设置一个键,但您的类没有实现该键/属性

然后你就遇到了不设置零值的问题。您可以告诉您的类不要用零值覆盖现有内容,方法是

覆盖-无效设置值:forKey:



在设置类时需要做更多的工作,但是当web服务扩展其返回的属性集时,它为您提供了未来的证明。

这与dpassage的答案是一样的。我不是有意要窃取他的想法;我们在同一时刻创造了答案。很抱歉。证明这是个好主意!这与帕萨奇的回答是一样的。我不是有意要窃取他的想法;我们在同一时刻创造了答案。很抱歉。证明这是个好主意!不过,我认为他不需要反省,是吗?难道键值编码还不够吗?我不认为键值编码能给你一个可用属性的列表,是吗?他说他想证明:“显然,我可以手动设置每个属性,但我不希望每次添加新属性时都必须更改此设置。“覆盖setNilValueForKey以不更新该键如何?我的解决方案已经在Obj-C运行时中遇到麻烦了。”。同时,KVO的主要部分似乎也是诱人的命运不过,我认为他不需要反省,是吗?难道键值编码还不够吗?我不认为键值编码能给你一个可用属性的列表,是吗?他说他想证明:“显然,我可以手动设置每个属性,但我不希望每次添加新属性时都必须更改此设置。“覆盖setNilValueForKey以不更新该键如何?我的解决方案已经在Obj-C运行时中遇到麻烦了。”。同时,KVO的主要部分似乎也是诱人的命运啊,对。这就是答案,比如说,有人攻击你的服务并在其中放了一些钥匙,你没有预料到,我。E班假设web服务已更新并具有新密钥,但您的用户仍运行旧版本?可以事先在字典上运行健全性检查,以删除任何额外的恶意密钥。除了明显的allKeys循环之外,还有什么办法可以做到这一点呢?如果web服务中存在不符合KVC的密钥,那么它们将被忽略,因为会重写forUndefinedKey方法。iOS8.1中的NSObject只有两个声明的属性,它们都是只读的,因此您无法使用恶意服务器代码更改它们@Aminegm Awad,您是否有一个可以使用您描述的方法设置的值的示例,该值会损害类的完整性?是的,只需更改一个键,假设在下一个版本中所有者被更改为具有数组的所有者。即使忽略所有者,也不会设置所有者。然后它被放在你的软件中任何地方的所有者集合中…这可能会损害软件的其余部分。最终,整个软件不能依赖任何设置。这会导致大量额外检查。答案中的通用解决方案非常吸引人,因为它们展示并使用了Objctive-C的强大功能。但决不能在网络或文件系统上使用它。做这样的事情不是KVC风格而是NSCoding风格。啊,是的。这就是答案,比如说,有人攻击你的服务并在其中放了一些钥匙,你没有预料到,我。E班假设web服务已更新并具有新密钥,但您的用户仍运行旧版本?可以事先在字典上运行健全性检查,以删除任何额外的恶意密钥。除了明显的allKeys循环之外,还有什么办法可以做到这一点呢?如果web服务中存在不符合KVC的密钥,那么它们将被忽略,因为会重写forUndefinedKey方法。iOS8.1中的NSObject只有两个声明的属性,它们都是只读的,因此您无法使用恶意服务器代码更改它们@Aminegm Awad,您是否有一个可以使用您描述的方法设置的值的示例,该值会损害类的完整性?是的,只需更改一个键,比如 ner在下一个版本中更改为具有数组的所有者。即使忽略所有者,也不会设置所有者。然后它被放在你的软件中任何地方的所有者集合中…这可能会损害软件的其余部分。最终,整个软件不能依赖任何设置。这会导致大量额外检查。答案中的通用解决方案非常吸引人,因为它们展示并使用了Objctive-C的强大功能。但决不能在网络或文件系统上使用它。这样做的方式是NSCoding风格而不是KVC风格。