我面临着一个大问题,我找不到解决方案的唯一原因是因为我缺乏对 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
操作左右后使您的控制器保持活动状态。 这些是编写管理良好的代码时应遵循的简单规则。