更改根视图控制器不会释放同一窗口上的先前视图控制器

Posted

技术标签:

【中文标题】更改根视图控制器不会释放同一窗口上的先前视图控制器【英文标题】:Changing the root view controller is not deallocating the previous view controllers on the same window 【发布时间】:2017-12-21 03:36:22 【问题描述】:

我的应用程序使用初始视图控制器启动(我们将其称为 StartVC)。现在,当用户按下继续按钮时,我将在 StartVC 之上显示一个导航堆栈(我们将其称为 RegisterVC)。此导航堆栈将包含 5 个视图控制器,每当用户使用按钮操作向前移动时,我都会将其推向它。在第 5 个视图控制器之后,我开始了一个新的导航堆栈(我们将其称为 LoginVC)。

现在我的用例是 我不希望 StartVCRegisterVC 驻留在内存中,因为一旦用户完成注册,它们就没有用了。为了实现这一点,我将 AppDelegate 窗口的根视图控制器更改为 LoginVC

以下是我在 RegisterVC 的第 5 个视图控制器上尝试的选项:

1) 更改按键窗口

    UIApplication.shared.keyWindow?.rootViewController = LoginVC
    UIApplication.shared.keyWindow?.makeKeyAndVisible()

2) 改变窗口

   let appDelegate = UIApplication.shared.delegate as! AppDelegate
   appDelegate.window?.rootViewController = LoginVC
   appDelegate.window?.makeKeyAndVisible()

3) 在分配新的根视图控制器之前,将之前的根视图控制器设为 nil。

   let appDelegate = UIApplication.shared.delegate as! AppDelegate
   appDelegate.window?.rootViewController = nil
   appDelegate.window?.rootViewController = LoginVC
   appDelegate.window?.makeKeyAndVisible()

4) 我还直接从 AppDelegate 尝试了上述选项,而不是从第 5 个视图控制器进行。

使用上述所有选项,我尝试通过查看所有视图控制器上的 deinit 进行调试,但没有一个被释放。此外,我可以在 xcode 调试视图层次结构中看到 LoginVC 下的第 5 个视图控制器。

由于没有将它们从内存中删除,我面临的实际问题是在呈现 LoginVC 之后,我有一个背景颜色 alpha 较小的视图控制器。因此,我在其下方看到了 RegisterVC 第 5 个视图控制器。

对此的任何帮助表示赞赏...

【问题讨论】:

我建议使用"debug memory graph" 功能来看看是什么保持对那些旧视图控制器的强引用。 你应该在这里回答:***.com/a/27153956/849645。如果你的问题和我的一样,这已经为我解决了。 【参考方案1】:

我认为 rootViewController 设置不是问题。也许您在其他视图控制器中有一个保留周期,阻止它们被释放。

有很多方法可能会导致您不小心做到这一点(在块中捕获对 self 的强引用,不将委托或其他反向引用标记为弱,等等)。

您也许可以使用 Instruments 来解决这个问题。这是一个教程:http://samwize.com/2016/05/30/finding-retain-cycle-with-instruments/

【讨论】:

或者使用 Rob 的 debug memory graph 的建议(见评论你的问题) 是的,看起来你们是对的,似乎有一个保留周期,但我无法弄清楚它发生在哪里......我遵循了“调试内存图”和“仪器”但没有结束...我正在谨慎地管理闭包内的“弱自我”和“弱委托引用”,但它仍然隐藏在某个地方...一旦我发现它发生在哪里,我会发布更新...谢谢你的快速反应.. 嗨@Venkat 对此有何更新?我面临着类似的问题,因为在切换控制器时之前的控制器仍然可见。 没有@PriyankaMistry,它仍然可见,我无法解决这个问题......我发现这个问题得到解决的唯一方法是在更改根控制器时将其关闭。 嗨@Naveen。终于找到retain cycle的原因了吗?我面临一个非常相似的问题,调试并没有帮助我找到问题的根源。

以上是关于更改根视图控制器不会释放同一窗口上的先前视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

UIViewController 在解除先前呈现的模态视图控制器后被释放

交替使用拆分视图控制器和导航控制器作为窗口根视图控制器

如何回到不同故事板的先前视图控制器?

当被模态视图控制器覆盖时,iOS 6 视图控制器布局在方向更改后不会更新

更改视图转换会更改 iOS 7 上的视图位置,但不会在 ios8 上更改视图位置

UINavigationController 上的 UIPageViewController 在更改方向后不会重新布局其子视图控制器