KVO:无法删除观察者

发布于 2025-01-03 22:11:12 字数 1321 浏览 1 评论 0原文

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

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

don 有一个 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 的路径“标题”,因为它未注册为 观察者。

In my interface I have an NSTextField who's value is bound to an NSArrayController's selection.selectedType.title. All of the NSArrayController's objects are custom objects each with two methods:

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

The don't have an iVar selectedType. However, they do have an iVar holding all MYType objects. The code boils down to this:

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

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

MYType objects got a NSString *title iVar with a corresponding @property and synthesize.

Whenever I call setSelectedType:, the changes are immediately visible in the NSTextField and everything seems to work but I get a log message saying:

Cannot remove an observer NSArrayController 0x141160 for the key
path "selectedType.title" from MYType 0x1a4830, most
likely because the value for the key "selectedType" has
changed without an appropriate KVO notification being sent. Check the
KVO-compliance of the MYType class.

I tried encapsulating the setSelectedType: method with willChangeValueForKey: and didChangeValueForKey: and then I still got a log message but a different one:

Cannot remove an observer NSKeyValueObservance 0x1c7570 for the key
path "title" from MYType 0x1a4be0 because it is not registered as an
observer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

碍人泪离人颜 2025-01-10 22:11:12

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

您还需要让 KVO 知道 selectedType 取决于 someIndex (和/或 someStuff;从您的蒸馏代码中不清楚)。

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

这告诉 KVO 系统,每当 someIndex 更改时,它都会导致 selectedType 发生隐式更改。请参阅 注册从属密钥

First, use accessors. Don't access your ivars directly. You're bypassing the KVO for someIndex because you modify the ivar directly. Don't touch ivars directly unless you have to.

You also need to let KVO know that selectedType depends on someIndex (and/or someStuff; it's not clear from your distilled code).

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

This tells the KVO system that whenever someIndex changes, it causes an implicit change in selectedType. See Registering Dependent Keys.

满栀 2025-01-10 22:11:12

我遇到了同样的错误,但原因不同。也许值得一提,以防其他人来到这里。

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

I ran into this same error but for a different reason. Probably worth mentioning it in case anyone else winds up here.

I'm writing an app in Swift and I'd forgotten to prefix the var with dynamic

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文