核心数据keyPathsForValuesAffectingValueForKey只调用关系,而不是属性

我正在使用核心数据来模拟具有属性和关系的实体。 我想使其中一个属性依赖于另外两个关系。

核心数据常见问题解答和其他一些示例使用+(NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key来达到此目的。 但是,这似乎只是要求我的所有关系属性,而不是任何属性。 另外keyPathsForValuesAffecting<key>永远不会被我的任何属性调用。

这是正常的行为,还是我错过了什么? 如何根据其他属性或属性计算一个属性,例如。 距离,通过设置一个startLocation和一个stopLocation?

看起来好像在几天之后find了我自己的问题的解决scheme,结果我错过了一些东西。

在重读了NSKeyValueObserving Protocol Reference中关于keysPathsForValuesAffectingValueForKey:方法的讨论之后,我意识到了下面这句话的含义:

当密钥的观察者注册到接收类的实例时,键值观察本身会自动观察同一个实例的所有密钥path,并在密钥观察者的值关键path的变化。

总之,你的实例应该有一个观察者观察你的属性<key>

 [myInstance addObserver:myObserver forKeyPath:attributeKey options:nil context:nil]; 

只要你有一个观察者注册,该协议将为您的特定属性键调用keysPathsForValuesAffectingValueForKey 。 如果此方法返回一组非空的键path,则除了通知您对属性进行任何直接更改之外,如果对这些键path中的任何一个进行了更改,则KVO将为您的属性发出更改通知。

关系键自动调用,因为核心数据已经使用观察者保持反向关系最新。

在特定情况下,如果您想拥有属性取决于同一个实体中的另一个属性或关系,则必须:

  1. 在使用addObserver:forKeyPath:options:context:的awakeFromInsert:方法中添加观察者addObserver:forKeyPath:options:context:
  2. 实现keyPathsForValuesAffectingValueForKey:keyPathsForValuesAffecting<key>
  3. 为您的属性键path实施observeValueForKeyPath:ofObject:change:context以对相关更改通知进行操作,即更新属性值。