更改rootViewController时,视图控制器保留另一个控制器

时间:2017-12-11 03:35:42

标签: ios viewcontroller presentviewcontroller deinit

我在应用中发现内存泄漏,其中包含以下内容:

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

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

到目前为止,这种方法运行良好 - 显示了另一个VC,并且调用了该函数的VC已被解除分配。

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

然后从ThirdVC调用appDelegate中的上述函数(通过使它成为rootViewController来显示viewController一个或两个),这个ThirdVC和呈现它的VC不会被释放。

知道为什么会这样吗?

如果需要,可以发布示例项目。如果这会产生任何不同,VC会从故事板中实例化。

1 个答案:

答案 0 :(得分: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
   })    
}