【问题标题】:Removing all previously loaded ViewControllers from memory iOS Swift从内存中删除所有以前加载的 ViewControllers iOS Swift
【发布时间】:2017-02-27 06:45:57
【问题描述】:

我目前正在编辑之前编写的代码, 在应用程序中,第一个 viewController 是一个名为 ListViewController 的表视图控制器,它有几个元素,每行选择都会创建一个视图控制器的新实例并以模态方式呈现它。但是在那些视图控制器中,之前的开发人员并没有将它们解散,而是再次创建了 ListViewController 的实例并以模态方式呈现它以返回。

应用程序显然正在使用大量内存。

关闭视图控制器不是一种选择。

如果我在堆栈中一个一个弹出视图控制器,这不起作用,每个视图都有弹出窗口等显示在 viewdidAppear 上。

我需要从内存中删除所有以前加载的 ViewController 并呈现一个 viewController 以便内存中没有任何 ViewController 的实例。 可能吗? 有没有办法我可以说一个名为 HomeViewController 的新 ViewController 确保所有视图控制器的所有先前加载的实例都被释放。

场景如下:

                         ListViewController 
                     /            |            \ 
             AViewController  BViewController  CViewController

ListViewController 有 3 个元素

一个 乙 C

用户可以点击它们中的任何一个,从而呈现一个 ViewController。 并且从每个视图控制器中,当按下后退按钮时,会显示 ListViewController。

使用以下代码显示视图:

if let listViewController = storyboard!.instantiateViewControllerWithIdentifier("ListViewController") as? ListViewController {
                    self.presentViewController(listViewController, animated: true, completion: nil)
                }

【问题讨论】:

  • 你不能保留一个布尔值来标记弹出窗口是否显示在 viewDidAppear 中吗?然后你可以弹出并且弹出窗口不会触发。但听起来整个事情都需要重构
  • 为什么不能解雇 VC?
  • 我同意,每个视图控制器都在使用不同的资源,中间甚至还有一个 SpriteKit 游戏场景。是否可以迁移到一个新的视图控制器来释放所有以前的视图控制器,就像应用程序刚刚启动一样,不需要任何属性或状态,只是一个新的开始。
  • @Sweeper 当我关闭一个 VC 时,显示前一个,我的意思是如果 ListViewController 正在呈现它们,那么解除非常简单,但是每个视图控制器要么呈现 ListViewController 要么呈现任何其他视图控制器。所以它可以是任何可能的组合,比如 ListViewControler -> A -> ListViewController -> B -> C -> A -> ListViewController -> A
  • @Hammadzafar 听起来后退按钮的实现很糟糕。您应该只更改后退按钮,以便它关闭/弹出 VC

标签: ios swift uiviewcontroller presentviewcontroller


【解决方案1】:

我不确定它会起作用。尝试这个。在提交任何新的ViewController之前。

AppDelegate中创建一个方法

func switchControllers(viewControllerToBeDismissed:UIViewController,controllerToBePresented:UIViewController) {
        if (viewControllerToBeDismissed.isViewLoaded && (viewControllerToBeDismissed.view.window != nil)) {
            // viewControllerToBeDismissed is visible
            //First dismiss and then load your new presented controller
            viewControllerToBeDismissed.dismiss(animated: false, completion: {
                self.window?.rootViewController?.present(controllerToBePresented, animated: true, completion: nil)
            })
        } else {
        }
    }

现在假设你像这样移动

ViewController --> 你点击一个按钮并呈现一个SecondViewController

所以目前我们在内存中有ViewControllerSecondViewController

现在,当您单击SecondViewController 中的某个按钮以显示ThirdViewController 时,SecondViewController 必须关闭。所以在SecondViewController按钮按下

@IBAction func buttonPress(_ sender: AnyObject) {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    let controllerToBePresented = self.storyboard?.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
    appDelegate.switchControllers(viewControllerToBeDismissed: self, controllerToBePresented: controllerToBePresented)
}

所以现在我们在内存中有ViewControllerThirdViewController
SecondViewController 已从内存中删除。

更好的解决方案是将您的控制器保留在UINavigationController 堆栈中,因为您可以获得一个所有ViewControllers 推送到堆栈上的数组。

【讨论】:

  • 谢谢,我试过了,但这不起作用。当我使用这段代码时,if 总是解析为 true,它既不会关闭当前的视图控制器,也不会呈现新的视图控制器。
  • 你要写dismiss的代码..我刚在cmets..First dismiss and then load your new presented controller
  • 是的,这就是我正在做的,这是代码:if oldVC.isViewLoaded() && oldVC.view.window != nil { oldVC.dismiss if let AVC = storyboard!.instantiateViewControllerWithIdentifier("A") as? AViewController { presentVC(AVC) } } else { if let AVC = storyboard!.instantiateViewControllerWithIdentifier("A") as? AViewController { presentVC(AVC) } } }
  • 你在哪里写这段代码?它应该是类必须存在于内存中的某个位置,例如 appDelegate。等我编辑
  • 我已经实现了您的解决方案,它适用于一些 VC,因此这意味着您的解决方案是正确的,快速提问,是否像我们一样关闭 ViewController,这会释放它正在使用的内存吗?因为我正在监控所使用的内存,并且我没有看到与之前的使用情况相比有任何变化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-30
  • 2022-11-07
  • 2013-12-14
  • 2018-10-05
相关资源
最近更新 更多