如何使用Key-Value Coding来判断对象是否存在一个对象?

我想testing一个对象是否在iPhone SDK中有一个可写的@property。

这样做的一个可能的方法是检查-valueForKey:方法,但这似乎相当不雅!

例:

@try { id *value = [instance valueForKey:@"myProperty"]; } @catch (NSException * e) { // Key did not exist } 

有没有更好的方法来做到这一点?

如果要创build正在检查的对象,则可以覆盖valueForUndefinedKey:setValue:forUndefinedKey以执行比引发exception更有用的操作。

另一方面,如果您试图在运行时反思您不了解的对象,则必须使用运行时方法来执行此操作。 您既可以使用objective-c运行时本身,也可以调用class_copyPropertyListprotocol_copyPropertyList并处理这些事件,或者使用Foundation并针对给定的属性调用KVC getter / setters对象的respondsToSelector ,例如,您将调用的属性foo就像[someObject respondsToSelector:NSSelectorFromString(@"foo")];

一般来说,没有办法确定某个对象是否具有给定键的值。 一个实例可以决定从-valueForUndefinedKey:方法返回一个否则未定义的键的值。 或者它可能会让默认实现抛出一个exception。 现代Objective-C(2.0)对象经常在其公共API中声明相关的属性。 对于这些对象,可以使用Objective-C运行时的class_copyPropertyListprotocol_copyPropertyList来获取可用属性的列表。 您也可以模拟KVCsearch列表,通过repondsToSelector:进行testingrepondsToSelector:如果实例响应适当的getter方法。 最后,你可以使用运行时的class_copyIvarList来检查一个合适的伊娃的ivars。 这是你不应该做很多工作。 它不能保证你知道一个对象实例是否会在发送valueForKey:消息时引发一个exception,并且表示一个更大的问题。

如果你有一个对象的集合必须为给定的键提供一个值,但是有一些则不是,那么你就有一个devise问题。 你应该定义一个适当的接口(Objective-C中的@protocol )来声明所需的属性。 然后,您可以testing是否符合此协议,或者使用编译器为您做一些编译时types检查,以确保实例符合协议(如果您正在传递单个实例)。