【问题标题】:Swift - Viewcontrollers not deinit when segue is performed [duplicate]Swift - 执行 segue 时视图控制器不会取消初始化 [重复]
【发布时间】:2019-10-13 04:49:05
【问题描述】:

我对内存管理和 ARC 的整个概念相当陌生。

我最近对其进行了调查,结果喜忧参半。

首先应该注意的是 some ViewController 会取消初始化,但我仍在学习和清理我的应用程序。

但是,我注意到的一个常见模式是,当我使用 navigationController?.popViewController(animated: true) 行时,如果没有强引用,这实际上是 deinit 视图控制器。

但是,我的问题是,当我使用 segue 并使用 performSegue(withIdentifier: "showDetail_Segue", sender: nil) 时,永远不会使用/调用 deinit 方法。 (我只有一个打印语句来指示视图是否已被取消初始化)。在大多数情况下,当我执行 segue 时,我会将数据传递给另一个视图控制器,因此,我使用以下函数 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {}。

我尝试将我的 segue 更改为 navigationController?.pushViewController(VC, animated: true),但我的应用程序崩溃了。

我在这里遗漏了什么吗?

当navigationController 为popped 时取消初始化的ViewControllers 在以编程方式执行segue 时也不会取消初始化。

有人可以告诉我我做错了什么吗?

谢谢。

【问题讨论】:

  • 很难说没有看到你的 performSegue 方法。我的猜测是你无意中在那里创建了一个强大的参考。
  • 我的perfomSegue方法是这样的override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "details_Segue" { let detailsVC = segue.destination as! DetailsViewController let text = sender as! String detailsVC.textDescription = text } }
  • 我重读了你的问题,我想我可能理解错了。让我输入一个答案。
  • 听起来你需要使用 unwind segue 来返回之前的 ViewController。请参阅this answer,了解如何创建和以编程方式调用展开转场。
  • @vacawama 正是我想要的!非常感谢。

标签: ios swift automatic-ref-counting deinit


【解决方案1】:

好吧,如果我理解正确的话,你可能对 segues 的工作方式有误解

Segues 不能用于返回堆栈中的前一个 viewController

这很重要。如果您使用 segues 作为返回而不是使用 popViewController 的方式,那么您将创建一个新的 viewController 实例,您将返回到所以 deinit 永远不会被调用,因为 viewController 仍在内存中。

基本上,类似这样的列表 -> 详细信息 -> 列表,您刚刚使用 segue 创建了列表的另一个实例。

【讨论】:

  • 我正在执行 segues 以转到单独的视图控制器。一些转义是在不同的UIStoryboard 中的ViewController。本质上,我正在做这个主页 -> 产品 -> 详细信息。可能我对deinit有误解。每当出现新的ViewController 时,我都会尝试释放内存。这仅在我使用 popViewController 时有效。
  • 不,您要使用的 viewController 不会 deinit,因为它不会从内存中删除。 Deinit 仅在控制器被销毁并释放内存时才起作用 - 您不希望它用于稍后需要返回的东西。
  • segues 可以用来返回,但是你需要使用一个unwind segue。
  • 我的立场是正确的。
【解决方案2】:

当您调用 performSegue 并且此 segue 是向另一个 VC 的推送时,您正在创建 VC 的新实例,但您的导航堆栈仍然是相同的,您只需将 VC 添加到堆栈中。

记住:

堆栈:[root, vc1, vc2]

vc2.performSegue(推送)

堆栈:[root, vc1, vc2, vc3]

该类仅在您解雇 VC 时调用 denit。

希望对你有帮助。

【讨论】:

  • 是否可以在我执行 segue 之前/之后“关闭”视图控制器?
  • 如果你正在关闭另一个没有执行 segue 的视图控制器,可能是的。
猜你喜欢
  • 1970-01-01
  • 2020-01-04
  • 2015-12-06
  • 1970-01-01
  • 2019-07-28
  • 2016-12-31
  • 2017-01-20
  • 2020-09-23
  • 1970-01-01
相关资源
最近更新 更多