0

I've found a memory leak in an app where the following is done:

Imagine two view controllers, each of which calls a function in the appDelegate similar to this:

func switchRootViewController() {    
    let vc = getTheOtherViewController()
    self.window?.rootViewController = vc
}

So far this is working well - the other VC is shown and the one that called the function is deallocated.

But when you present a third view controller from first or second VC via: present(ThirdViewController(), animated: true)

And then call the above function in the appDelegate from ThirdVC (to show viewController one or two by making it the rootViewController), this ThirdVC and the VC that presented it do not get deallocated.

Any idea why that is?

Can post sample project if needed. VC's are instantiated from storyboard if that makes any difference.

Alexandre G
  • 1,655
  • 20
  • 30

1 Answers1

1

You are messing up the view hierarchy here. You should dismiss all the presented view controllers of the current rootViewController before switching to the new one. This is the only solution I've found to work!

Your switchRootViewController method should be like below,

func switchRootViewController() {    
   if var topController = UIApplication.shared.keyWindow?.rootViewController {
        while let presentedViewController = topController.presentedViewController {
            topController = presentedViewController
        }
        topController.dismiss(animated: true, completion: {
            let vc = getTheOtherViewController()
            self.window?.rootViewController = vc
        })
    }
}

If you there are multiple view controllers presented,

func switchRootViewController() {   
   self.view.window!.rootViewController?.dismiss(animated: true, completion: {
      let vc = getTheOtherViewController()
      self.window?.rootViewController = vc
   })    
}
Shamsudheen TK
  • 30,739
  • 9
  • 69
  • 102
  • 1
    Thanks for the answer. Not sure I get the difference between the two functions: 1. Aren't `self.view.window!.rootViewController` and `UIApplication.shared.keyWindow?.rootViewController` the same? 2. In first func you I see you dismiss the topmost view controller, in second - the root view controller. Can you please explain why? – Alexandre G Dec 14 '17 at 04:24
  • They are same. The difference is, first function will dismiss only the top presented view controller. The second function will dismiss all the presented view controllers that you presented from the current rootViewController. if the solution helps, please accept the answer :) happy coding. – Shamsudheen TK Dec 14 '17 at 13:46