如何通过ViewControllers管理和释放内存 [英] How can I manage and free memory through ViewControllers

查看:150
本文介绍了如何通过ViewControllers管理和释放内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm in front of a big issues, and the only reason I can't find a solution is because my lack of knowledge about swift and memory management in swift. So here is my concerns. I'm working in swift 4.0 and iOS 9.3

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

I'm actually making a picture gallery app with login/logout. Basic application. I'm working in cleanSwift So I don't have those HUGE ViewControllers.

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

My application is separate in 3 VC : The login, the gallery and the settings (which contains the LogOut).

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

Here is my problem. When I log out, I want to create a new loginVC and clear all previous VC. So I have my cleanMemory function which set all the UIImage to 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的休息符

and then I delete the rests of the UIImage and the 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次时,我的应用程序崩溃,因为我管理不好我的内存_

But when I create my new LoginVC.. my RAM didn't decrease.. And when I check the app memory, not a single VC was deleted.. And when I execute the loop Logout/Login 3 times, my app crash because I'm not well managing my RAM_

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

So where did I get wrong, and why ??

谢谢你的回答。

编辑:我有2个问题:


  • 我的completionHandler保留了我的VC live

  • 我用.present切换VC,这样就把我的VC留在了内存中。

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

So you should change VC like that :

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)并返回上一个视图控制器时,您已经销毁了该控制器。

To remove viewController from memory you simply need to remove it from navigation stack. So when you call navigationController?.popViewController(animated: true) and back to previous view controller you already destroy that controller.

然后,


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

Here is my problem. When I log out, I want to create a new loginVC and clear all previous VC. So I have my cleanMemory function which set all the UIImage to nil

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

on logout it's good practice to stop all request but you don't need to do any changes to UI, because it takes some time and it doesn't need to "remove controller from memory". How to check if view controller completely removed from navigation stack? Simply write print statement in deinit func, compile code and go back from this view controller.

deinit {
    print("ViewController deinit")
}

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

If this print works fine (you can see text in xcode console), you achieve the result - controller has been removed from navigation stack, but if there is no print result you probably forget to right manage your closures. For example

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

当您认为控制器已经解除分配时,此关闭可能会占用您的控制器,这意味着您的控制器存在于某处在记忆中。要防止这些保留周期,您需要使用 [无主自我] [弱自我] (只是谷歌这个关键字,这很容易理解)像这样:

this closure may hold your controller when your think that controller already deallocated and it means that your controller present somewhere in memory. To prevent these retain cycles you need to use [unowned self] of [weak self] (just google for this keywords, it's very easy to understand) like this:

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

因此,在这种情况下有在从导航堆栈中弹出操作之后,没有任何东西可以让你的控制器保持活着状态。
这些是编写管理良好的代码时应遵循的简单规则。

So, in this case there are nothing that can hold your controller alive after pop from navigation stack action or so. These are simple rules that you should follow to write well managed code.

这篇关于如何通过ViewControllers管理和释放内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆