我正在尝试实现我自己的NSViewController版本(为了向后兼容),我遇到了绑定问题:由于绑定保留了目标,每当我绑定File的所有者时,我都会有一个保留圈。
所以我想我只是明确地从超级视图中删除我的视图并释放顶级对象,这会照顾绑定,因为我的控制器不再持有视图了,所以他们释放了我我可以离开但由于某种原因,我的视图控制器仍然没有被释放。这是一个展示问题的示例应用程序:
http://dl.dropbox.com/u/34351/BindingsLeak.zip
构建它,启动它,然后点击Cmd-K(“编辑”菜单中的“创建笔尖”)将NIB加载到空窗口中。再次点击Cmd-K以释放第一个视图控制器(TestNibOwner)并加载一个新视图控制器。但是旧的视图控制器永远不会被解除分配。
删除复选框上的“value”绑定,它就会被释放。
如果在release / retain / autorelease覆盖中设置断点,则会看到_NSBindingInfo保留TestNibOwner,但从不在泄漏的情况下释放它。
任何人都知道如何解决这个问题?
答案 0 :(得分:2)
对class-dump和朋友进行一些调查,看起来Apple有一个名为NSAutounbinder的私有类,负责处理NSViewController和NSWindowController等类的脏工作。无法真正说明它是如何工作的或如何复制它。
所以,我无法真正回答你关于如何防止加载笔尖中的任意绑定发生保留周期的问题,但也许知道Apple在作弊并且你没有遗漏任何明显的东西是一些安慰。 : - )
答案 1 :(得分:1)
我为同一个问题做的一件事是在我的笔尖内创建一个代理NSObjectController。我的类似NSViewController的类有一个指向此代理的指针,所有绑定都通过它绑定。当我想清理视图控制器时,我在对象控制器上执行[selfProxy setContent:nil]并释放视图控制器。在这种情况下,NSObjectController代理在这种情况下充当自动解绑器。
它更加手动,你不能只是自己发布视图,但它确实解决了保留问题。
我建议你这样做:
-(void) releaseTopLevelObjects
{
// Unbind the object controller's content by setting it to nil.
[selfProxy setContent:nil];
NSLog( @"topLevelObjects = %@", topLevelObjects );
[topLevelObjects release];
topLevelObjects = nil;
}
在你的笔尖中,绑定会通过如下路径发生:
selfProxy.content.representedObject.fooValue
答案 2 :(得分:0)
当你从超级视图中删除你的视图时,你是否还发送了另一个 - 发布消息?它是通过从笔尖取消归档创建的,对吧?