我面临着一个大问题,而我无法找到解决方案的唯一原因是因为我对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 _
那我哪里出错了,为什么?
谢谢你的回答。
编辑:我有两个问题:所以你应该像这样改变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
答案 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
...
})
动作之后,没有任何东西可以让你的控制器保持活着状态。
这些是编写管理良好的代码时应遵循的简单规则。