【问题标题】:KVO: Cannot remove an observerKVO:无法移除观察者
【发布时间】:2012-02-08 18:05:48
【问题描述】:

在我的界面中,我有一个NSTextField,他的value 绑定到一个NSArrayController's selection.selectedType.title。所有NSArrayController's 对象都是自定义对象,每个对象都有两种方法:

- (MYType *)selectedType;
- (void)setSelectedType: (MYType *)type;

没有有 iVar selectedType。但是,他们确实有一个 iVar 保存所有 MYType 对象。代码归结为:

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

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

MYType 对象有一个 NSString *title iVar 和对应的 @propertysynthesize

每当我致电setSelectedType: 时,更改都会立即在NSTextField 中可见,并且一切似乎都正常,但我收到一条日志消息:

无法删除观察者 NSArrayController 0x141160 的键 来自 MYType 0x1a4830 的路径“selectedType.title”,最 可能是因为键“selectedType”的值有 更改时未发送适当的 KVO 通知。检查 MYType 类的 KVO 兼容性。

我尝试用willChangeValueForKey:didChangeValueForKey: 封装setSelectedType: 方法,然后我仍然收到一条日志消息,但消息不同:

无法删除观察者 NSKeyValueObservance 0x1c7570 的键 来自 MYType 0x1a4be0 的路径“标题”,因为它没有注册为 观察者。

【问题讨论】:

    标签: objective-c cocoa-bindings key-value-observing nsarraycontroller key-value-coding


    【解决方案1】:

    首先,使用访问器。不要直接访问您的 ivars。您正在绕过 someIndex 的 KVO,因为您直接修改了 ivar。除非必须,否则不要直接接触 ivars。

    您还需要让 KVO 知道 selectedType 依赖于 someIndex(和/或 someStuff;从您的提炼代码中不清楚)。

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

    这告诉 KVO 系统,无论何时 someIndex 发生变化,都会导致 selectedType 的隐式变化。见Registering Dependent Keys

    【讨论】:

      【解决方案2】:

      我遇到了同样的错误,但原因不同。可能值得一提,以防其他人在这里结束。

      我正在用 Swift 编写一个应用程序,但我忘记在 var 前面加上 dynamic

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-16
        • 1970-01-01
        • 1970-01-01
        • 2014-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多