您可以手动执行Cocoa绑定?

问题描述 投票:36回答:4

我在实现我自己的NSView子类绑定了一条缝。它的工作原理,但也有从榫文件绑定到文件的所有者时,保留周期的问题。读入了一点之后,我发现苹果有同样的问题在几年前但有一些神奇的无证类(NSAutounbinder)固定它。

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

我的问题是:有没有什么办法,使这项工作自定义绑定,以及由苹果公司生产的一部分,而无需使用无证功能?我要对这个错误的方式?


更新2:我已经找到了解决方案,允许手动实现绑定酷似苹果的绑定工作。它充分利用了无证NSAutounbinder类的,实际上并没有使用未记录的功能。我将在今天晚些时候发布的解决方案。


更新:我已经使用exposeBinding:审判,它似乎并没有任何区别。然而,NSObject实施bind:toObject:withKeyPath:options:一半的作品。它propogates从bindee变化与粘合剂(即,从模型/控制器查看),但不工作相反的方式。此外,虽然明显被观察的bindee,observeValueForKeyPath:ofObject:change:context:永远不会触发。

示例项目在这里:http://www.tomdalling.com/wp-content/BindingsTest.zip

苹果的文档表示你做什么,其实,要重写bind:toObject:withKeyPath:options:实现手动绑定。在这里看到:http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html


边注:我已经调查无证NSAutounbinder是如何工作的,这里是我所知道的。

当创建一个NSWindowController的结合,结合的对象实际上是从NSWindowController获取与NSAutounbinder - [NSWindowController _autounbinder]。 NSAutounbinder对于NSWindowController对象的非固定代理。它是非固定,以避免挡周期问题。

当 - [NSWindowController发布]被称为和retainCount == 1,NSAutounbinder解除绑定所有绑定到自身。这确保了没有悬摆指针对象就被释放了。

objective-c cocoa cocoa-bindings
4个回答
22
投票

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

基本上,你不会覆盖bind:toObject:withKeyPath:options:unbind:。在NSObject默认实现将使用NSAutounbinder避免保留周期。正如路易斯Gerbarg指出,仍有一些NSAutounbinder不踢的情况。但是,你可以得到你的绑定工作至少还有苹果的绑定。

由于bind:toObject:withKeyPath:options:的默认实现不更新模型时视图的变化,查看驱动的变化必须手动传播。您可以使用-[NSObject infoForBinding:]获得所有必要的信息来更新绑定的对象。我已经添加了我自己的方法在NSObject的一个类别:

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

它处理获取绑定的对象,绑定的关键路径和应用价值变压器。实现可从顶部的链接。


3
投票

简单的答案是,不,你不能把它与调用代码和豆瓣没有解决方法工作。即使NSAutounbinder错过某些情况下为NSDocument和NSWindowController,如果苹果不能让它正常工作2班,他们专门搭起我们这些没有获得了AppKit的内部结构已经基本没有机会。

话虽如此,有两个解决方法是,也许比windowWillClose解除绑定更好一点:。

  1. 不要绑定到文件的所有者,而是拖了NSObjectController为根级别对象到笔尖并绑定到这一点,那么setContents:awakeFromNib期间对象控制器上。
  2. 打开垃圾收集。如果这是一个选项,它解决了所有的对象周期的问题;-)显然GC推出了自己的问题,如果你需要10.4兼容性它是一个非首发。

3
投票

请参阅如何实现自己绑定一个很好的例子mmalc的GraphicsBindings例子。您需要实现NSKeyValueBindingCreation非正式协议得到它的工作。为了让你的控制器知道有事情可以绑定,调用exposeBinding在+(ID)初始化视图的方法:

+ (void)initialize { [self exposeBinding:@"ILIKEBINDAGE"]; }

然后,您需要实现每个绑定管理在NSKeyValueBindingCreation协议方法。基本上,您需要设置为KVO视图,以便它知道基于应用程序的行为何时更新和处理清理(解除绑定:)。

这是一个很大的额外费用,相当丑陋的代码,所以它可能是使用传统的胶水代码工作更好,更容易阅读。


2
投票

您可能要检查出NSKeyValueBindingCreation Protocol。它可以让你通过编程代码创建绑定。 (记得做在awakeFromNib方法的工作,如果你需要引用IBOutlet中变量或他们可能是零。)

© www.soinside.com 2019 - 2024. All rights reserved.