为什么KVO在新旧值相同时发送更改通知?

时间:2013-07-16 18:45:05

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

我有一个实体,它是NSManagedObject的一个子类,叫做Event。我还为KVO更改通知注册了此实体的一些建模属性:

[self.event addObserver:self
             forKeyPath:@"numGuests"
                options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                context:&numGuestsContext];

[self.event addObserver:self
             forKeyPath:@"checkedIn"
                options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                context:&checkedInContext];

[self.event addObserver:self
             forKeyPath:@"seatedCount"
                options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
                context:&seatedContext];

然而,即使更改字典中的NSKeyValueChangeOldKey和NSKeyValueChangeNewKey的值相等,似乎也会触发observeValueForKeyPath方法通知。

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
    NSNumber *oldValue = [change valueForKey:NSKeyValueChangeOldKey];
    NSNumber *newValue = [change valueForKey:NSKeyValueChangeNewKey];

    if ([oldValue isEqualToNumber:newValue])
    {
        return;
    }

现在我已经采取了快速的理智检查,看看它们是否相等,但我想理解为什么这个通知会在开始时被解雇?

更新:@jszumski在评论中提到这种情况最有可能发生,因为虽然逻辑上相同但对象不同。 Event实体对象总是具有相同的地址,但是我观察的对象(实体中的属性)不断更改地址,但我不确定为什么?

我想知道在bg查询线程中访问此值是否会导致Core Data在具有相同值的实体中创建新的内部对象?

1 个答案:

答案 0 :(得分:13)

简单地说,您正在假设NSKeyValueObservingOptions的功能。它们不像你期望的那样工作。您仅发送的标志决定更改字典的内容是。每当调用setter时,观察者都会始终

此外,当您发送标志时,实际上只是说“我想要旧值和新值。我不在乎是否他们是否平等“。

请阅读参考资料以了解更多信息:

  

NSKeyValueObservingOptions

     

这些常量传递给addObserver:forKeyPath:options:context:   并确定作为更改的一部分返回的值   字典传递给了   observeValueForKeyPath:ofObject变化:背景:。你可以传递0   不需要更改字典值。