你可以手动实现Cocoa绑定吗? [英] Can you manually implement Cocoa bindings?

查看:89
本文介绍了你可以手动实现Cocoa绑定吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在为自己的NSView子类实现绑定时遇到了一个问题。它工作,但是当从一个nib文件绑定到文件的所有者时,保留周期有问题。阅读了一下后,我发现苹果在几年前也有同样的问题,但是已经修复了一些魔法无记录的类(NSAutounbinder)。

I've had a crack at implementing bindings for my own NSView subclass. It works, but there are problems with retain cycles when binding to File's Owner from a nib file. After reading into it a little, I discovered that Apple had the same problem a few years back but have fixed it with some magic undocumented class (NSAutounbinder).

在这里长时间讨论保留周期问题 http:// www。 cocoabuilder.com/archive/message/cocoa/2004/6/12/109600 。解决方法是在窗口控制器释放之前,而不是在释放之前,在windowWillClose:等地方取消绑定所有绑定。这似乎是对我不必要的黑客。

There is a lengthy discussion of the retain cycle problem here http://www.cocoabuilder.com/archive/message/cocoa/2004/6/12/109600 . The workaround is to to unbind all bindings before the window controller is released, not before it is deallocated, in a place like windowWillClose:. This seems like an unnecessary hack to me.

我的问题是这是有什么办法使自定义绑定工作,以及苹果,而不使用未公开的功能?

My question is this: Is there any way to make custom bindings that work as well as the ones made by Apple, without using undocumented features? Am I going about this the wrong way?

更新2:我发现一个解决方案允许手动实现的绑定工作就像苹果的绑定。它利用了无文档的NSAutounbinder类,而不实际使用未记录的特性。

UPDATE 2: I have found a solution that allows manually implemented bindings to work exactly like Apple's bindings. It takes advantage of the undocumented NSAutounbinder class, without actually using undocumented features. I will post the solution later today.

UPDATE:我试过使用 exposeBinding:,它似乎没有任何区别。但是, NSObject 实现 bind:toObject:withKeyPath:options:一半。它传播从bindee到binder的变化(即从模型/控制器到视图),但不会以相反的方式工作。此外,虽然bindee显然被观察,但 observeValueForKeyPath:ofObject:change:context:不会被触发。

UPDATE: I've tried using exposeBinding:, and it doesn't seem to make any difference. However, the NSObject implementation of bind:toObject:withKeyPath:options: half works. It propogates changes from bindee to binder (i.e. from model/controller to view), but doesn't work the opposite way. Also, although the bindee is obviously being observed, observeValueForKeyPath:ofObject:change:context: is never triggered.

示例项目位于此处: http://www.tomdalling.com/wp-content/BindingsTest。 zip

Apple的文档表明,事实上,你必须重写 bind:toObject:withKeyPath:options:来实现手动绑定。请参阅: http://developer.apple.com/documentation /Cocoa/Conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html

Apple's documentation indicates that you do, in fact, have to override bind:toObject:withKeyPath:options: to implement manual bindings. See here: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html

注意:我已调查了无证NSAutounbinder工程,这里是我知道的。

SIDE NOTE: I've investigated how the undocumented NSAutounbinder works, and here's what I know.

当向NSWindowController创建绑定时,绑定对象实际上是一个NSAutounbinder,它从NSWindowController与 - [NSWindowController _autounbinder]获取。 NSAutounbinder是NSWindowController对象的非保留代理。

When a binding is created to an NSWindowController, the bound object is actually an NSAutounbinder that is acquired from the NSWindowController with -[NSWindowController _autounbinder]. NSAutounbinder is a non-retaining proxy for the NSWindowController object. It is non-retaining to avoid the retain cycle problem.

当 - [NSWindowController release]被调用并且retainCount == 1时,NSAutounbinder解除绑定到自身的所有绑定。这可以确保在释放对象之前,没有指向对象的悬挂指针。

When -[NSWindowController release] is called and retainCount == 1, The NSAutounbinder unbinds all bindings to itself. This ensures that there are no dangling pointers to the object before it is deallocated.

推荐答案

这里是我能找到的最佳解决方案。我在这里有更详细的讨论和演示代码: http: //tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/

Here is the best solution I can find. I've got a more detailed discussion and demo code here: http://tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/

基本上,您不要 override bind:toObject:withKeyPath:options: unbind:。在 NSObject 上的默认实现将使用 NSAutounbinder 来避免保留周期。正如Louis Gerbarg指出的,仍然存在 NSAutounbinder 不能引入的情况。但是,您可以使绑定至少与Apple的绑定一样工作。

Basically, you DO NOT override bind:toObject:withKeyPath:options: or unbind:. The default implementation on NSObject will use NSAutounbinder to avoid retain cycles. As Louis Gerbarg pointed out, there are still situations where NSAutounbinder doesn't kick in. However, you can get your bindings working at least as well as Apple's bindings.

因为 bind:toObject:withKeyPath:options:的默认实现不会在视图更改时更新模型, - 必须手动传播驱动的更改。您可以使用 - [NSObject infoForBinding:] 获取更新绑定对象所需的所有信息。我已经添加了我自己的方法在NSObject类别:

Because the default implementation of bind:toObject:withKeyPath:options: doesn't update the model when the view changes, view-driven changes must be propagated manually. You can use -[NSObject infoForBinding:] to get all the information necessary to update the bound object. I've added my own method on NSObject with a category:

-(void)propagateValue:(id)value forBinding:(NSString*)binding;

它处理获取绑定对象,绑定的键路径和应用值transform。该实现可从顶部的链接获得。

It handles getting the bound object, the bound key path, and applying the value transformer. The implementation is available from the link at the top.

这篇关于你可以手动实现Cocoa绑定吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆