【问题标题】:How does NSViewController avoid bindings memory leak? [have sample app]NSViewController 如何避免绑定内存泄漏? [有示例应用程序]
【发布时间】:2010-01-17 13:46:13
【问题描述】:

我正在尝试实现我自己的 NSViewController 版本(为了向后兼容),但我遇到了绑定问题:由于绑定保留了它们的目标,所以每当我通过 File 的所有者绑定时,我都有一个保留圈。

所以我想我只是从其父视图中显式删除我的视图并释放顶级对象,这将处理绑定,因为我的控制器不再保留视图,所以它们释放了我我可以走了。但是由于某种原因,我的视图控制器仍然没有被释放。这是一个展示该问题的示例应用程序:

http://dl.dropbox.com/u/34351/BindingsLeak.zip

构建它,启动它,然后点击 Cmd-K(“编辑”菜单中的“创建 Nib”)将一个 NIB 加载到空窗口中。再次按下 Cmd-K 以释放第一个视图控制器 (TestNibOwner) 并加载一个新的。不过,旧的视图控制器永远不会被释放。

删除复选框上的“值”绑定,它就可以正常释放了。

如果您在 release/retain/autorelease 覆盖处设置断点,您会看到 _NSBindingInfo 保留了 TestNibOwner,但在泄漏的情况下从不释放它。

有人知道如何解决这个问题吗?

【问题讨论】:

  • 对不起,我不想先下载项目来帮助你。你能提供一些代码吗?

标签: objective-c memory-leaks nib xib appkit


【解决方案1】:

与 class-dump 和朋友一起做一些调查,看起来 Apple 有一个名为 NSAutounbinder 的私有类,它负责为 NSViewController 和 NSWindowController 等类处理这项肮脏的工作。无法真正说出它是如何工作的或如何复制它。

所以,我无法真正回答您关于如何防止在加载的 nib 中的任意绑定发生保留周期的问题,但知道 Apple 正在作弊可能是一种安慰,而且您没有遗漏任何明显的东西. :-)

【讨论】:

    【解决方案2】:

    我为同样的问题做的一件事是在我的笔尖内创建一个代理 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
    

    【讨论】:

    • 谢谢!我已经在网络上看到了许多骇人听闻的修复尝试,但这是我实际上敢于发布的解决方法。可惜没有真正的方法来进行自动解除绑定。
    【解决方案3】:

    当您从其超级视图中删除您的视图时,您是否还向它发送了另一个 -release 消息?它是通过从 ni​​b 取消归档创建的,对吧?

    【讨论】:

    • 是的,releaseTopLevelObjects 释放视图(以及可能存在的任何其他未归档对象)。至少这是它应该做的。
    猜你喜欢
    • 2018-08-29
    • 2012-11-30
    • 2011-06-17
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多