【问题标题】:View controller retaining another when changing rootViewController更改 rootViewController 时视图控制器保留另一个
【发布时间】:2018-05-24 13:42:35
【问题描述】:

我在执行以下操作的应用中发现了内存泄漏:

想象一下两个视图控制器,每个视图控制器调用 appDelegate 中的一个函数,类似这样:

func switchRootViewController() {    
    let vc = getTheOtherViewController()
    self.window?.rootViewController = vc
}

到目前为止,它运行良好 - 显示了另一个 VC,调用该函数的那个​​被释放了。

但是当您通过以下方式从第一个或第二个 VC 呈现第三个视图控制器时: present(ThirdViewController(), animated: true)

然后从 ThirdVC 调用 appDelegate 中的上述函数(通过将其设置为 rootViewController 来显示 viewController 一或二),此 ThirdVC 和呈现它的 VC 不会被释放。

知道为什么会这样吗?

如果需要,可以发布示例项目。如果有任何区别,VC 会从情节提要中实例化。

【问题讨论】:

  • "first of second VC via"
  • @Honey 是的,会更正谢谢
  • 请添加示例代码

标签: ios viewcontroller presentviewcontroller deinit


【解决方案1】:

您在这里搞乱了视图层次结构。在切换到新视图控制器之前,您应该关闭当前 rootViewController 的所有显示视图控制器。这是我发现的唯一可行的解​​决方案!

您的switchRootViewController 方法应如下所示,

func switchRootViewController() {    
   if var topController = UIApplication.shared.keyWindow?.rootViewController {
        while let presentedViewController = topController.presentedViewController {
            topController = presentedViewController
        }
        topController.dismiss(animated: true, completion: {
            let vc = getTheOtherViewController()
            self.window?.rootViewController = vc
        })
    }
}

如果你有多个视图控制器,

func switchRootViewController() {   
   self.view.window!.rootViewController?.dismiss(animated: true, completion: {
      let vc = getTheOtherViewController()
      self.window?.rootViewController = vc
   })    
}

【讨论】:

  • 感谢您的回答。不确定我明白这两个功能之间的区别: 1. self.view.window!.rootViewControllerUIApplication.shared.keyWindow?.rootViewController 不一样吗? 2.在第一个函数中,我看到您关闭了最顶层的视图控制器,第二个是根视图控制器。你能解释一下为什么吗?
  • 它们是一样的。不同之处在于,第一个函数只会关闭顶部呈现的视图控制器。第二个函数将关闭您从当前 rootViewController 呈现的所有呈现的视图控制器。如果解决方案有帮助,请接受答案 :) 快乐编码。
猜你喜欢
  • 2016-05-17
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
  • 1970-01-01
  • 1970-01-01
  • 2016-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多