核心数据:观察相关实体的变化

时间:2011-05-30 07:42:12

标签: objective-c ios core-data key-value-observing

我有一个示例管理对象模型,如下图所示。我想要发生的是:当更改Bar对象中货币关系的值的对象时,自动将相同的对象设置为所有与该Bar相关的Foos中的货币关系。 foos的关系。

enter image description here

我是否理解这可以通过KVO完成?我倾向于首先将其添加到Foo.m:

+ (NSSet *)keyPathsForValuesAffectingCurrency {
    return [NSSet setWithObject:@"bar.currency"];
}

但我无法弄清楚这是否正确或我将如何继续前进。谢谢你的任何建议。

2 个答案:

答案 0 :(得分:3)

您想要实现的目标当然是可能的,KVO可以解决这个问题。你只需要实现一些东西。

1。注册观察影响您房产的钥匙

您可以在对象醒来时将对象添加为观察者。

- (void) awakeFromInsert {
  [super awakeFromInsert];
  [self addObserver:self forKeyPath:@"bar.currency" options:NSKeyValueObservingOptionNew context:nil];
}

// Repeat for awakeFromFetch

请注意,这种情况适用于这种情况,因为这是一对一的关系。

2。触发通知时采取行动

currency的通知被解除时更新bar.currency的值

- (void) observeValueForKeyPath:(NSString *)keyPath
                       ofObject:(id)object
                         change:(NSDictionary *)change
                        context:(void *)context
{
  if( [keyPath isEqualToString:@"bar.currency"] ) {
    [self setValue:[self valueForKeyPath:@"bar.currency"] forKey:@"currency"];
  }

  // The rest of your KVO logic ...
}

替代方法

正如您所指出的,这也可以通过实现从属密钥

来完成
+ (NSSet *)keyPathsForValuesAffectingCurrency {
  return [NSSet setWithObject:@"bar.currency"];
}

在这种情况下,您必须观察@"currency"。在observeValue...方法中,您必须检查此密钥。最后,您必须使用setPrimitiveValue:forKey而不是setValue:forKey:设置值。这是因为后者会导致新的通知并导致无限循环。

答案 1 :(得分:1)

有几种可能的解决方案:

  1. 覆盖Bar中setCurrency的setter以更改Foo中的货币
  2. 如果Bar的货币发生变化,请使用KVOADC)更新Foo的关系。小心将KVO与Core Data结合使用(撤消处理和故障是棘手的)
  3. 如果这是您问题的最佳解决方案,请重新考虑您的数据模型