【发布时间】: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