你能手动实现Cocoa绑定吗?

Tom*_*ing 36 cocoa objective-c cocoa-bindings

我在实现自己的NSView子类的绑定方面遇到了麻烦.它工作正常,但是当从nib文件绑定到File的Owner时,保留周期存在问题.在阅读了一下之后,我发现Apple在几年前遇到了同样的问题,但已经修复了一些魔法未记录的类(NSAutounbinder).

这里有关于保留周期问题的冗长讨论http://www.cocoabuilder.com/archive/message/cocoa/2004/6/12/109600.解决方法是在释放窗口控制器之前取消绑定所有绑定,而不是在取消分配窗口控制器之前,在windowWillClose:之类的位置解除绑定.这似乎是对我不必要的黑客攻击.

我的问题是:有没有办法让自定义绑定与Apple制作的绑定一样好,而不使用未记录的功能?我是以错误的方式来做这件事的吗?


更新2:我找到了一个解决方案,允许手动实现的绑定与Apple的绑定完全一样.它利用了未记录的NSAutounbinder类,而没有实际使用未记录的功能.我将在今天晚些时候发布解决方案.


更新:我尝试过使用exposeBinding:,似乎没有任何区别.但是,NSObject执行bind:toObject:withKeyPath:options:半部作品.它传播从bindee到binder的变化(即从模型/控制器到视图),但不会以相反的方式工作.此外,虽然明显地观察到了这个垃圾箱,但是observeValueForKeyPath:ofObject:change:context:从未触发过.

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

Apple的文档表明,事实上,您必须覆盖bind:toObject:withKeyPath:options:以实现手动绑定.请看:http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html


侧面注意:我已经调查了未记录的NSAutounbinder如何工作,这就是我所知道的.

当为NSWindowController创建绑定时,绑定对象实际上是一个NSAutounbinder,它是从NSWindowController获取的 - [NSWindowController _autounbinder].NSAutounbinder是NSWindowController对象的非保留代理.避免保留循环问题是不保留的.

当调用 - [NSWindowController release]并且retainCount == 1时,NSAutounbinder会解除对所有绑定的绑定.这可确保在取消分配对象之前没有悬挂指针.

Tom*_*ing 22

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

基本上,你不要覆盖bind:toObject:withKeyPath:options:unbind:.默认实现NSObject将用于NSAutounbinder避免保留周期.正如Louis Gerbarg所指出的那样,仍有一些情况NSAutounbinder不会发生.但是,你可以使你的绑定工作至少与Apple的绑定一样好.

由于默认实现bind:toObject:withKeyPath:options:在视图更改时不更新模型,因此必须手动传播视图驱动的更改.您可以使用-[NSObject infoForBinding:]获取更新绑定对象所需的所有信息.我在NSObject上添加了我自己的方法,其中包含一个类别:

-(void)propagateValue:(id)value forBinding:(NSString*)binding;
Run Code Online (Sandbox Code Playgroud)

它处理获取绑定对象,绑定键路径和应用值转换器.可以从顶部的链接获得实施.