KVO:无法移除观察者

4
在我的界面中,我有一个 NSTextField,它的 value 绑定到了一个 NSArrayControllerselection.selectedType.title。所有的 NSArrayController 对象都是自定义对象,每个对象都有两个方法:
- (MYType *)selectedType;
- (void)setSelectedType: (MYType *)type;

这段代码中没有一个名为selectedType的iVar变量。然而,它们确实有一个持有所有MYType对象的iVar变量。代码可归纳为以下形式:

- (MYType *)selectedType
{
   if (someIndex == 0)
        return [types objectAtIndex: 0];
    else
        return [self typeWithIndex: someIndex];
}

- (void)setSelectedType: (MYType *)type
{
     someIndex = [type index];  
}

MYType对象有一个相应的@propertysynthesize,其中包含一个NSString *title iVar。

每当我调用setSelectedType:时,在NSTextField中立即看到更改,并且一切似乎都正常工作,但是我收到了一条日志消息:

无法删除观察者NSArrayController 0x141160,因为该值的键“selectedType”在没有发送适当的KVO通知的情况下已更改。请检查MYType类的KVO兼容性。

我试图使用willChangeValueForKey:didChangeValueForKey:封装setSelectedType:方法,然后我仍然收到了一条日志消息,但是这是不同的:

无法删除观察者NSKeyValueObservance 0x1c7570,因为它未注册为观察者。

2个回答

5

首先,使用访问器。不直接访问实例变量。因为您直接修改实例变量,所以绕过了 someIndex 的 KVO。除非必须这样做,不要直接操作实例变量。

您还需要让 KVO 知道 selectedType 依赖于 someIndex(以及/或者 someStuff;从您的简化代码中并不清楚)。

+ (NSSet *)keyPathsForValuesAffectingSelectedType
{
  return [NSSet setWithObjects:@"someIndex", nil];
}

这告诉了KVO系统,在someIndex发生变化时,会导致selectedType的隐式变化。请参见注册依赖键


1

我遇到了同样的错误,但原因不同。可能值得一提以防其他人也遇到同样的问题。

我正在使用Swift编写应用程序,但我忘记在变量前加上dynamic


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接