1

Upon app start, i have a login screen, which is an instance of LoginViewController and on success, i.e. after my user is successfully logged in, the main content of my app is being shown using the performSegue(withIdentifier identifier: String, sender: Any?) method to an instance of a UITabBarController. Unfortunately i deinit() is not being called on my LoginViewController after the segue. This does not happen due to any reference cycles i might have in my LoginViewController, because i explicitely checked for those.

Since a login screen is only required once upon app start, i was wondering if there is a best practice to be able to make sure that my LoginViewController is being deallocated after the segue?

Maybe using a segue is just not the right way to achive this, because from what i understand, the conclusion of a similar question Deinit not called on Show Detail segue was the fact, that using a showDetail-segue is the same as using a modal presentation, i.e. both controllers keep a reference to each other and deinit() will not be called in either of them. Is this really ecpected behavior, or am i missing something?

Update: The reason i care so much, is the fact that i am using RxSwift and my LoginViewController is subscribed on several Observables, so after my app leaves the LoginViewController, i want to make sure to set my collected DisposeBag to nil. Would it be finde to do this in the ViewDidDisappear() of my LoginViewController?

Alienbash
  • 554
  • 7
  • 17
  • 1
    You could try with replacing your rootViewController after successfull login: (UIApplication.shared.delegate as? AppDelegate)?.window?.rootViewController = yourTabBarController – Predrag Samardzic Nov 25 '17 at 17:12
  • Thanks, but unfortunately that does not change anything. The same issue occurs when using a segue from a ViewController, which is not the rootViewController. – Alienbash Nov 25 '17 at 18:32
  • 1
    The reason you can't dealloc the login screen is because your Tab Bar can be dismissed (you might not want it to happen, but the API is there). There's not much you can do here besides some sort of container view controller that swaps the login controller with the tab one, or overriding the root as suggested – Bruno Rocha Nov 25 '17 at 21:37
  • 1
    you have to show us the code which how you **get to** your LoginViewController and you **move away** from it. Simply because you segued away from a viewController doesn't mean it will get deallocated. You have to either **`dismiss`** it or **`pop`** it. If you don't what is the difference between dismiss and pop then see [here](https://stackoverflow.com/questions/11080091/dismissviewcontrolleranimated-vs-popviewcontrolleranimated). Having that said I think you're doing neither and just segueing hence it's never getting deallocated. – mfaani Nov 25 '17 at 23:07
  • 1
    or if you don't know the difference between **`present`** and **`push`** then see [here](https://stackoverflow.com/questions/14233017/difference-between-presentviewcontroller-and-uinavigationcontroller) – mfaani Nov 25 '17 at 23:10
  • 1
    Additionally I highly recommend you see [Best practices for Storyboard login screen, handling clearing of data upon logout](https://stackoverflow.com/questions/19962276/best-practices-for-storyboard-login-screen-handling-clearing-of-data-upon-logou). It will show you how you must structure your screens and what kind of segues you should be using... – mfaani Nov 25 '17 at 23:13

1 Answers1

0

I would suggest you to create a custom segue class and override the perform function like this:

class CustomSegue: UIStoryboardSegue {
    override func perform() {
        source.view.window?.rootViewController = destination
    }
}
Ruslan Serebriakov
  • 640
  • 1
  • 4
  • 12