-->

您可以手动执行Cocoa绑定?(Can you manually implement Cocoa b

2019-06-26 13:43发布

我在实现我自己的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解除绑定所有绑定到自身。 这确保了没有悬摆指针对象就被释放了。

Answer 1:

这是我能找到的最好的解决方案。 我有一个更详细的讨论和演示代码在这里: 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;

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



Answer 2:

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

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

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


Answer 3:

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

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

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

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



Answer 4:

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



文章来源: Can you manually implement Cocoa bindings?