KVO:无法删除观察者
在我的界面中,我有一个 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 以及相应的 @property
和 synthesize
。
每当我调用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,使用访问器。不要直接访问您的 ivars。您绕过了
someIndex
的 KVO,因为您直接修改了 ivar。除非必要,否则不要直接触摸 ivars。您还需要让 KVO 知道
selectedType
取决于someIndex
(和/或someStuff
;从您的蒸馏代码中不清楚)。这告诉 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 onsomeIndex
(and/orsomeStuff
; it's not clear from your distilled code).This tells the KVO system that whenever
someIndex
changes, it causes an implicit change inselectedType
. See Registering Dependent Keys.我遇到了同样的错误,但原因不同。也许值得一提,以防其他人来到这里。
我正在用 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