我正在以编程方式创建所有显示对象并将它们添加到我的 Storyboard场景 subview 中。
例如:
let button: UIButton = UIButton( frame: CGRect( x: 0, y: 0, width: 160, height: 50 ) )
self.view.addSubview( button )
更改 Storyboard场景时,我遇到了巨大的内存泄漏(每次场景更改之间的内存使用量几乎翻倍),这当然表明更改场景时这些对象不会自动删除。我读过一些有关 Swift 中垃圾收集的内容,但没有找到有关此特定用例的太多信息。
通过更改 Storyboard场景,我的意思是通过当前 View Controller ,如下所示:
self.presentViewController( targetController, animated: true, completion: nil )
话虽如此,我的问题是:
1)删除对象可以像这样完成:
button.removeFromSubview()
button = nil
正确吗?
2) 有没有办法删除循环中插入 View subview 的任何对象,并将其分配给 nil 以完全删除与该对象关联的任何引用?我可以将它们一一删除,但这是一项艰巨的任务。
3)是否有办法在更改场景后自动从内存中删除对象?这将是最好的解决方案。
如果能提供一个解决方案的示例,我们将不胜感激。
提前致谢。
最佳答案
一些可能需要澄清的事情:
1) 通过 Storyboard 添加的按钮(标记为 @IBOutlet 的按钮)很弱;您不需要将它们清零,因为您对它们的引用不会将它们保留在内存中。
2) presentViewController
可能不会按照您期望的方式运行。最重要的是,不要用新的 View Controller 替换现有的 View Controller ;它从旧 View Controller “呈现”新 View Controller 。为了说明这一点,您可以从新的 View Controller 调用 self.presentingViewController ,这将为您提供对先前 View Controller 的引用;它仍然在内存中。
但是, View Controller 并不是很大,并且当它们不在屏幕上时,它们的 View 会被卸载。但是,如果您在呈现 View Controller 中保留一些大型资源,这些资源将持续存在。我建议通过在 viewWillAppear/viewDidAppear (而不是 viewDidLoad)中加载这些资源来解决这个问题,然后在prepareForSegue: 或 viewDidDisappear 中卸载它们(我认为 didDisappear 没有被一致调用存在一些长期存在的问题?我有某种心理上的想法)那里有标志,但我不确定来源是什么......)
或者,如果您真正想要做的是完全更改为新的 Root View Controller ,您可以通过 AppDelegate 的 .window 属性来完成此操作,如下所示:
let storyboard = UIStoryboard(named: "NewStoryboard", bundle: nil)
let newVC = storyboard.instantiateInitialViewController
UIApplication.sharedApplication().delegate.window.rootViewController = newVC
不过,我不会过度使用这个;它在您可能在首次启动时显示教程,然后想要加载正常 View 层次结构的地方最有用。
关于memory - 切换 Storyboard场景时从内存中删除对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26608816/