【问题标题】:NSView not being deallocatedNSView 没有被释放
【发布时间】:2019-08-09 02:03:32
【问题描述】:

我在这里遇到了一个奇怪的情况,这几乎可以肯定是因为我是 macOS 开发的新手,而且我缺少一些核心知识。

我有一个以编程方式显示的模式表。 (我没有使用故事板转场,因为它需要是验证的结果,到目前为止我还没有看到以编程方式启动转场的方法 - 如果有人有建议,这是一个子问题)

这是我的做法:

searchVC = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "SearchSceneIdentifier") as? SearchViewController
    if searchVC != nil {
        searchVC!.searchTerm = searchTextField.stringValue
        self.presentAsSheet(searchVC!)
    }

这很好地展示了表格并让我与它互动。在其中,我使用了一个具有委托的类来返回异步搜索查询。

奇怪的是当我打电话时

self.view.window!.close()

从视图控制器内部,我认为视图控制器不会被释放。这似乎是因为委托仍然连接到它,即使具有此委托的对象在视图控制器本身的范围内。该委托似乎将视图控制器保存在内存中。

在关闭窗口之前我已经通过这样做来解决这个问题:

search.delegate = nil

但这对于其他有相同问题的视图控制器来说不是一个好的解决方案,因为它们在窗口内,我不想捕捉窗口关闭然后向每个视图控制器发送某种通知以消除 -确定他们的代表。

另一种似乎也是错误的方法是,我在应用程序委托中保留对这些窗口的引用并从那里对其进行 nil-ify。

所有这些似乎都是解除分配问题的讨厌解决方案,我希望有一种更清洁的方法来解决这个问题。在 Objective-C 中,引用计数一直是个问题,但有一些模式可以干净地处理它们。

任何建议表示赞赏。

【问题讨论】:

  • presentAsSheet(_:) 的文档说“要关闭工作表,请在自身(呈现视图控制器)上调用 dismiss(_:) 方法。”。
  • 确实如此,谢谢。但是这样做而不将委托设置为 nil 会导致视图控制器保持分配状态并继续接收委托方法调用。
  • 代表是否拥有指向工作表的链接?还是有其他东西与工作表有很强的链接?
  • 从我的测试来看,delegate 似乎是唯一有链接的东西。不过,您使用了“强”这个词——这可以通过使委托成为其类中的弱变量来解决吗?它目前被定义为 public var delegate : SearchDelegate?
  • 您的委托属性应该很弱。这是一个常见的场景。由于这些保留周期问题,委托属性几乎总是应该被声明为弱。

标签: swift macos cocoa delegation nsviewcontroller


【解决方案1】:

我将所有代表都更新为weak var,这解决了我在解除分配方面的所有问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-24
    • 2021-11-20
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    相关资源
    最近更新 更多