如何通过ViewControllers管理和释放内存

时间:2018-01-04 13:52:29

标签: ios swift memory

我面临着一个大问题,而我无法找到解决方案的唯一原因是因为我对swift和内存管理缺乏了解。所以这是我的担忧。我在swift 4.0和iOS 9.3中工作

我实际上正在制作一个带登录/注销的图片库应用程序。基本申请。 我在cleanSwift工作所以我没有那些巨大的ViewControllers。

我的应用程序在3 VC中是独立的:登录,图库和设置(包含LogOut)。

这是我的问题。当我退出时,我想创建一个新的loginVC并清除以前的所有VC。 所以我有我的cleanMemory函数,它将所有UIImage设置为nil

func cleanMemory(request: Gallery.Request) { // Interactor
    worker.cleanMemory(completionHandler: { (Value) in

        self.interventions?.removeAll() // Interventions contains UIImages
        self.interventionsSelected.removeAll() // InterventionsSelected contains UIImages

    })

}

然后我删除了UIImage和VC的休止符

func cleanMemory() {

    interactor?.cleanMemory(request: Gallery.Request())
    self.displayedInterventions.removeAll() // displayedInterventions contains UIImages
    interactor = nil
    router = nil
    self.removeFromParentViewController()
    self.navigationController?.popViewController(animated: true)
}

但是当我创建新的LoginVC时......我的RAM没有减少..当我检查应用程序内存时,没有删除单个VC ..当我执行循环注销/登录3次时,我的应用程序崩溃,因为我不能很好地管理我的RAM _

那我哪里出错了,为什么?

谢谢你的回答。

编辑:我有两个问题:

  • 我的completionHandler让我的VC保持活力
  • 我用.present切换VC,这样就把我的VC留在了内存中。

所以你应该像这样改变VC:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationVC = storyboard.instantiateViewController(withIdentifier: "LoginController")
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = destinationVC

1 个答案:

答案 0 :(得分:3)

要从内存中删除viewController,您只需将其从导航堆栈中删除即可。因此,当您调用navigationController?.popViewController(animated: true)并返回上一个视图控制器时,您已经销毁了该控制器。

然后,

  

这是我的问题。当我退出时,我想创建一个新的loginVC并清除以前的所有VC。所以我有我的cleanMemory函数,它将所有UIImage设置为nil

注销时停止所有请求的良好做法,但您不需要对UI进行任何更改,因为它需要一些时间,并且不需要"删除来自记忆的控制器"。如何检查视图控制器是否完全从导航堆栈中删除?只需在print func中编写deinit语句,编译代码并从此视图控制器返回。

deinit {
    print("ViewController deinit")
}

如果此print工作正常(您可以在xcode控制台中看到文本),则可以实现结果 - 控制器已从导航堆栈中删除,但如果没有print结果,您可能会忘记正确管理您的关闭。例如

worker.cleanMemory(completionHandler: { (Value) in
    ...
})

当您认为控制器已经解除分配时,此闭包可能会占用您的控制器,这意味着您的控制器存在于内存中的某个位置。要阻止这些retain cycles,您需要使用[unowned self]的{​​{1}}(只需谷歌获取此关键字,这很容易理解),如下所示:

[weak self]

因此,在这种情况下,在// or you can use `[unowned self]` worker.cleanMemory(completionHandler: { [weak self] (Value) in guard let `self` = self else { return } // only for `weak` way ... }) 动作之后,没有任何东西可以让你的控制器保持活着状态。 这些是编写管理良好的代码时应遵循的简单规则。