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

问题描述 投票:0回答:1

我面临着一个大问题,而我无法找到解决方案的唯一原因是因为我对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
ios swift memory
1个回答
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][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
    ...
})

所以,在这种情况下,在pop from navigation stack动作之后,没有任何东西可以让你的控制器保持活着。这些是编写管理良好的代码时应遵循的简单规则。

© www.soinside.com 2019 - 2024. All rights reserved.