如何通过视图控制器管理和释放内存



我面临着一个大问题,我找不到解决方案的唯一原因是因为我缺乏对 swift 和 swift 内存管理的知识。这就是我的担忧。我正在使用 swift 4.0 和 iOS 9.3

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

我的应用程序在 3 个 VC 中是分开的:登录名、图库和设置(包含注销)。

这是我的问题。注销时,我想创建一个新的登录VC并清除所有以前的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)
}

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

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

谢谢你的回答。

编辑:我有2个问题:

我的
  • 完成处理程序使我的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

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

然后

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

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

deinit {
print("ViewController deinit")
}

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

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

当您认为控制器已经释放时,此闭包可能会保留控制器,这意味着您的控制器存在于内存中的某个位置。为了防止这些retain cycles你需要像这样使用[weak self][unowned self](只是谷歌这个关键字,很容易理解):

// or you can use `[unowned self]`
worker.cleanMemory(completionHandler: { [weak self] (Value) in
guard let `self` = self else { return } // only for `weak` way
...
})

因此,在这种情况下,没有什么可以在pop from navigation stack操作左右后使您的控制器保持活动状态。 这些是编写管理良好的代码时应遵循的简单规则。

最新更新