Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dismiss ViewController after transition to release memory

I want to free up memory my ViewController used after dismissing it. I use the following code to present the new ViewController and dismiss the old one:

let sB: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newVC: UIViewController = sB.instantiateViewController(withIdentifier: "MyVC")
self.present(newVC, animated: true, completion: { x in
    oldVC.dismiss(animated: false, completion: { _ in //oldVC: variable keeping track of currently visible view controller
        print("done")
    })
})

This code successfully presents newVC and prints done after dismissing oldVC. However, my memory still stays as high as it was when having oldVC on screen.
What am I doing wrong?

FYI

  • I am using ENSwiftSideMenu
    • Since I didn't get it to work in a different way, all my ViewControllers are a subclass of ENSideMenuNavigationController
  • I am getting console warnings about detached views and views not being in the window hierarchy
  • for all ViewControllers, both presentingViewController and presentedViewController are nil
like image 900
LinusGeffarth Avatar asked Sep 23 '16 12:09

LinusGeffarth


People also ask

How do I remove ViewController from memory?

You can't remove a view controller from within itself (i.e. viewDidDisappear) - what you need to do is to remove all references to it, at which point ARC will deallocate it.

How do I dismiss a presented ViewController?

When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it. In other words, whenever possible, the same view controller that presented the view controller should also take responsibility for dismissing it.

How do you dismiss a popover?

To dismiss the popover after creation, call the dismiss() method on the Popover instance. The popover can also be dismissed from within the popover's view by calling the dismiss() method on the ViewController.


2 Answers

Check the following issues:

  1. You should dismiss the old ViewController before present a new ViewController, or you will dismiss the new one at the same time.
  2. Swift using ARC to manage memory. The oldVC is not released since some objects have a strong reference to it. Make an example, i have a ViewController with a variable tableView. The tableView will release when the ViewController released. But at the same time if you link it to another ViewController that is not released, the tableView will not release although the previous ViewController is released.

Solution:

  1. Present a UINavigationController and using setViewControllers to manage the transition of your ViewControllers.
  2. Remove the useless reference of the oldVC

If you really do not understand. You can search:

  1. ARC
  2. UIViewController transition
like image 125
jhd Avatar answered Sep 30 '22 16:09

jhd


Your oldVC will not be deallocated, since your newVC (and any UIViewController) keeps by default a strong reference to its presentingViewController - the controller that presented it. If this was not the case, you would never be able to safely dismiss your newVC without disturbing the view hierarchy.

As far as your specific problem is concerned, in order to deallocate your old view controller, I would suggest dismissing the oldVC first and then display your newVC from another ViewController, earlier in the stack (could be the UIApplication shared().keyWindow?.rootViewController)

like image 27
spassas Avatar answered Sep 30 '22 16:09

spassas