【问题标题】:Receiving 2 KVO notifications for a single KVC change为单个 KVC 更改接收 2 个 KVO 通知
【发布时间】:2011-05-26 00:14:59
【问题描述】:

我正在使用 KVC/KVO 为大学项目创建自定义绑定实现(它需要自定义,因为我想做超出绑定可以做的事情,包括在 iOS 上运行)。

我有一个“绑定控制器”,它在对象上的多个键上注册 KVO 通知(使用 addObserver:forKeyPath:options:context:)并且我确实收到了通知。但是,每次更改我都会收到两个通知。我有一个解决方法的想法,但我宁愿找出为什么会发生这种情况并纠正它!

有没有人知道为什么会发生这种情况?我确定我只注册了每个通知一次,而取消注册一次会导致两个通知都停止。

谢谢。

编辑:

我有一些代码的请求,所以我会放一些。目前有点粗糙,它本质上仍然是一个概念证明,所以请耐心等待。

这是我正在观察的属性之一(我知道这有点奇怪,但这个类本质上将 NSManagedObject 的某些属性公开为自身的属性):

- (void)setName:(NSString *)name
{
    [self willChangeValueForKey:@"name"];
    [contact setFirstName:name];
    [self didChangeValueForKey:@"name"];
}

这是我用来观察该属性的代码(确认只运行一次,并且只在一个地方):

[viewModel addObserver:self
            forKeyPath:@"name"
               options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial)
               context:viewController];

之后任何更改该属性的调用,例如:

viewModel.name = @"Joe";
[viewModel setName: @"Joe"];
[viewModel setValue: @"Joe" forKey: @"name"];

会导致方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

被调用两次,每次都使用相同的参数。

【问题讨论】:

    标签: objective-c cocoa macos key-value-observing


    【解决方案1】:

    你正在这样做:

    - (void)setName:(NSString *)name
    {
        [self willChangeValueForKey:@"name"];
        [contact setFirstName:name];
        [self didChangeValueForKey:@"name"];
    }
    

    但是(听起来)来自非NSManagedObject 子类。这意味着 Cocoa 将尝试自动为您发送 KVO 通知。你也通过发送你自己的来补充它。解决方案:

    • 覆盖+automaticallyNotifiesObserversForKey: 以返回NO
    • 将您的方法更改为:

      - (void)setName:(NSString *)name { [contact setFirstName:name]; }

    【讨论】:

    • 太棒了,这似乎已经解决了。如果您自己实现访问器,我不知道 Cocoa 会自动发送这些事件。谢谢!
    【解决方案2】:

    也许在您的 addObserver 调用中添加一个 NSLog,以查看您是否添加了两个观察者。

    【讨论】:

    • 我已经检查过了,addObserver 调用只存在于一个方法中,并且我已经确认该方法只运行一次。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多