为单个KVC更改接收2个KVO通知

时间:2010-12-15 15:47:06

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

我正在使用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

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

2 个答案:

答案 0 :(得分:22)

你这样做:

- (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]; }

答案 1 :(得分:1)

也许在NSLog来电中加addObserver,看看你是否添加了两名观察员。