9

我有一个实体,它是 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 在评论中提到,这很可能是因为对象不同,但逻辑上相等。事件实体对象始终具有相同的地址,但是我正在观察的对象(实体中的一个属性)不断更改地址,尽管我不确定为什么?

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

4

1 回答 1

14

简单地说,您假设NSKeyValueObservingOptions. 它们不像您期望的那样工作。您发送的标志仅决定更改字典的内容是什么。每当调用 setter 时,总是会触发观察者。

此外,当您发送标记oldnew时,实际上只是说“我想要旧值和新值。我不在乎它们是否相等”。

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

NSKeyValueObservingOptions

这些常量被传递给 addObserver:forKeyPath:options:context: 并确定作为传递给 observeValueForKeyPath:ofObject:change:context: 的更改字典的一部分返回的值。如果您不需要更改字典值,则可以传递 0。

于 2013-07-16T22:53:31.390 回答