手动 Cocoa 绑定不改变观察到的 KeyPath

发布于 2024-11-18 23:26:35 字数 1894 浏览 1 评论 0原文

我正在以编程方式更改可可绑定。我将 NSTextField 的值绑定到 ArrayController 的选择。手动更改绑定后,我收到“不符合键的键值编码..”错误,键是旧键,而不是新键。

查看代码:

NSTextField *textField = [self listTextField];   

NSDictionary *currentBindInfo = [textFieldTableViewCell infoForBinding:NSValueBinding];
NSLog(@"pre-change bindings for textField: %@", currentBindInfo);

/* Change the binding.  [Tried unbind: first, no difference] */
[textField bind:NSValueBinding
                      toObject:[currentBindInfo valueForKey:NSObservedObjectKey] 
                   withKeyPath:@"objectValue.iLifeProductName"
                       options:[currentBindInfo valueForKey:NSOptionsKey]];

/* Log the info so we can confirm it changed. debugging. */
NSLog(@"post-change bindings for textField: %@", [textFieldTableViewCell infoForBinding:NSValueBinding]);

为了排除故障,我在更改之前和之后调用了“infoForBinding”,并且看起来更改正确。我可以看到旧值,然后我调用 bind:toObject... 并第二次转储 infoForBinding,绑定的值已更改:

2011-07-06 22:36:23.137 My App 2011[14640:407] pre-change bindings for listTextFieldTableViewCell: {
NSObservedKeyPath = "selection.osxProductName";
NSObservedObject = "...sameTextField... 0x4009cc380>";
NSOptions =     {...same... };
}

2011-07-06 22:36:23.138 My App 2011[14640:407] post-change bindings for listTextFieldTableViewCell: {
NSObservedKeyPath = "selection.iLifeProductName";
NSObservedObject = "...sameTextField... 0x4009cc380>";
NSOptions =     {...same... };
}

但代码仍在调用原始密钥:

2011-07-06 22: 36:23.231 My App 2011[14640:407] [ valueForUndefinedKey:]:实体 ILifeVersion 不符合键的键值编码“osx产品名称”。

--

NSArrayController 绑定到 ManagedObjectContext,实体名称之前已更改:

  [[self listAC] setEntityName:entityName];

原始 keyValuePath 是否缓存在我需要清除的地方?当我更改观察到的键路径时,是否有类似 willChange/didChangeValueForKeyValuePath 的消息需要发送到绑定或 arrayController ?

有想法吗?

谢谢!

I'm changing a cocoa binding programatically. I'm binding a NSTextField's value to the selection of an ArrayController. After I manually change the binding, I'm getting the "not key-value coding compliant for the key.." error, with the key being the old key, not the new one.

Check out the code:

NSTextField *textField = [self listTextField];   

NSDictionary *currentBindInfo = [textFieldTableViewCell infoForBinding:NSValueBinding];
NSLog(@"pre-change bindings for textField: %@", currentBindInfo);

/* Change the binding.  [Tried unbind: first, no difference] */
[textField bind:NSValueBinding
                      toObject:[currentBindInfo valueForKey:NSObservedObjectKey] 
                   withKeyPath:@"objectValue.iLifeProductName"
                       options:[currentBindInfo valueForKey:NSOptionsKey]];

/* Log the info so we can confirm it changed. debugging. */
NSLog(@"post-change bindings for textField: %@", [textFieldTableViewCell infoForBinding:NSValueBinding]);

To troubleshoot, I call 'infoForBinding' before and after the change and it looks to be changed correctly. I can see the old value, then I call bind:toObject... and dump the infoForBinding a second time, and the value has changed for the binding:

2011-07-06 22:36:23.137 My App 2011[14640:407] pre-change bindings for listTextFieldTableViewCell: {
NSObservedKeyPath = "selection.osxProductName";
NSObservedObject = "...sameTextField... 0x4009cc380>";
NSOptions =     {...same... };
}

2011-07-06 22:36:23.138 My App 2011[14640:407] post-change bindings for listTextFieldTableViewCell: {
NSObservedKeyPath = "selection.iLifeProductName";
NSObservedObject = "...sameTextField... 0x4009cc380>";
NSOptions =     {...same... };
}

But the code is still calling the original key:

2011-07-06 22:36:23.231 My App 2011[14640:407] [ valueForUndefinedKey:]: the entity ILifeVersion is not key value coding-compliant for the key "osxProductName".

--

The NSArrayController is bound to a ManagedObjectContext, the entity name is being changed earlier with this:

  [[self listAC] setEntityName:entityName];

Is the original keyValuePath being cached somewhere that I need to clear out? Is there a message like willChange/didChangeValueForKeyValuePath that I need to send to the binding or arrayController when I change the observed keypath?

Ideas?

Thanks!

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

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

发布评论

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

评论(1

嘴硬脾气大 2024-11-25 23:26:35

正如 @noa 指出的,您正在查看单元上的绑定,但更改其控件上的绑定。这肯定会导致问题(咳咳)。

将这个: 替换

[textField bind:NSValueBinding
                  toObject:[currentBindInfo valueForKey:NSObservedObjectKey] 
               withKeyPath:@"objectValue.iLifeProductName"
                   options:[currentBindInfo valueForKey:NSOptionsKey]];

为:

[textFieldTableViewCell bind:NSValueBinding
                  toObject:[currentBindInfo valueForKey:NSObservedObjectKey] 
               withKeyPath:@"objectValue.iLifeProductName"
                   options:[currentBindInfo valueForKey:NSOptionsKey]];

看看它是否工作得更好。


对此的解释有点晦涩难懂,而且我是凭记忆做的,所以如果我弄错了一些细节,请原谅。

因为 NSControls 和它们的 NSCell 工作得非常紧密,所以在大多数情况下您实际上可以绑定到控件或单元格,并且您将得到非常相似的结果。也就是说,如果控件已绑定到,控件中有代码可以调用其 NSCell 上的正确方法,反之亦然。

这意味着,在 XIB 中,如果您绑定到其中一个或其他事物就会起作用,这很好。这还意味着如果每个视图有多个单元格,您可以绑定到一个单元格,所以这很好。然而,它可能会导致混乱,因为事实上您实际上可以绑定到您的视图及其单元格,并且实际上以不同的方式绑定它们,然后它们就会串扰。

在您的示例中,我相信除了 NSCell 上的绑定之外,您还向 NSControl 添加了第二个绑定。你是双重束缚的。那可不好。

就最佳实践而言,我尝试仅绑定到 NSControls,除非我有充分的理由下拉到 NSCells。部分是因为它与我在 XIB 中所做的相匹配,部分是因为任何标准都有助于减少这个问题,部分是因为 NSCells 正在被温和地弃用。

As @noa pointed out, you’re looking at the binding on the cell, but changing the binding on its control. That’s bound (ahem) to cause problems.

Replace this:

[textField bind:NSValueBinding
                  toObject:[currentBindInfo valueForKey:NSObservedObjectKey] 
               withKeyPath:@"objectValue.iLifeProductName"
                   options:[currentBindInfo valueForKey:NSOptionsKey]];

with this:

[textFieldTableViewCell bind:NSValueBinding
                  toObject:[currentBindInfo valueForKey:NSObservedObjectKey] 
               withKeyPath:@"objectValue.iLifeProductName"
                   options:[currentBindInfo valueForKey:NSOptionsKey]];

And see if it works better.


The explanation for this is a bit arcane, and I’m doing it from memory, so please excuse me if I get some of the details wrong.

Because NSControls and their NSCell works so closely together, you can actually bind to either the control or the cell in most instances, and you’ll get very similar results. That is, there’s code in the control to call the proper methods on its NSCell if the control’s been bound to, and vice-versa.

This means that if, in XIB, you bind to one or the other things will work, which is good. It also means you can bind to a cell in cases where you have multiple cells per view, so that’s good. HOWEVER, it can lead to confusion, because in fact you can actually bind to both your view and its cell, and in fact bind them in different ways, and then they’ll crosstalk.

In your example, I believe you’re adding a second binding to the NSControl in addition to the one on its NSCell. You’re doubly-bound. That’s no good.

In terms of best practice, I try to bind only to NSControls unless I have a good reason to drop down to NSCells. Partly because it matches what I do in XIB, partly because any standard helps reduce exactly this problem, and partly because NSCells are being gently deprecated.

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