更改根视图控制器不会释放同一个窗口上的先前视图控制器
我的应用程序启动时使用初始视图控制器(我们称之为StartVC)。现在,当用户按下继续按钮时,我将在StartVC之上呈现一个导航堆栈(可称为RegisterVC)。这个导航堆栈将包含5个视图控制器,每当用户向前移动按钮操作时,我都会按下它。在第五个视图控制器之后,我开始一个新的导航堆栈(我们称之为LoginVC)。更改根视图控制器不会释放同一个窗口上的先前视图控制器
现在我的使用情况是我不想让StartVC & RegisterVC驻留在内存,因为它们是没有用的,一旦用户完成注册。为了实现这一点,我改变了AppDelegate中窗口的根视图控制器LoginVC
下面是我试过的RegisterVC第五视图控制器上的选项:更改keywindow
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)将前一个根视图控制器设置为零,然后分配一个新视图控制器。
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = nil
appDelegate.window?.rootViewController = LoginVC
appDelegate.window?.makeKeyAndVisible()
4)我也尝试了直接从AppDelegate的上述选项,而不是从第五个视图控制器做它。
以上所有的选项,我试着通过在所有视图控制器上查看deinit进行调试,但是没有一个被取消分配。另外,我可以在xcode Debug View Hierarchy中看到LoginVC下的第五个视图控制器。
由于没有从内存中删除它们,我面临的实际问题是在呈现LoginVC之后,我有一个视图控制器,其背景色alpha更少。正因为如此,我在其下看到RegisterVC 5th视图控制器。
对此赞赏的任何帮助...
我认为rootViewController设置不是问题。也许你在其他视图控制器中有一个保留周期,可以阻止它们被释放。
有很多方法可能会意外地执行此操作(捕获对块中自身的强引用,不将代表或其他后引用标记为弱等)。
你可能可以通过仪器找出它。这里有一个教程:http://samwize.com/2016/05/30/finding-retain-cycle-with-instruments/
或使用Rob的调试内存图的建议(请参阅您的问题的评论) –
是啊,看起来你们是对的,似乎有一个保留周期,但我无法找出它发生的地方......我跟着'调试内存图表'和'工具',但没有结束......我谨慎地管理内部关闭和'弱代理引用'中的'弱自我',但它仍然隐藏在某个地方......我会发现一次更新在哪里发生......感谢您的快速回复。 – Venkat
Hi @Venkat对此有何更新?我正面临类似的问题,因为前一个控制器在切换控制器时仍然可见。 –
在设置新的根视图控制器之前,删除以前的根视图控制器。
private func removePreviousViewController() {
let previousViewController = self.window?.rootViewController
previousViewController?.dismiss(animated: true, completion: {
previousViewController?.view.removeFromSuperview()
})
}
我建议使用[ “调试内存图”](https://*.com/questions/30992338/how-to-debug-memory-leaks-when-leaks-instrument-does-not -show-them/30993476#30993476)功能,以查看对这些旧视图控制器保持强大的参考。 – Rob
你应该在这里回答:http://*.com/a/27153956/849645。如果你的问题与我的问题相同,这就为我解决了问题。 – CMont