user2875404
user2875404

Reputation: 3218

WatchKit: reloadRootControllers not removing controller (object persists, I want it to get destroyed)

I am trying to implement a login-scheme in WatchKit (whether or not having the user type data into his Watch shouldn't be of concern here) which means that after logging in, the user should see a view that doesn't let him go back to the login screen (no < at the top left corner)

If users get kicked out of their session (e.g. when not paying their subscription) I want the app to go back to the login screen.

Redirecting from the login screen to the main screen works fine using

DispatchQueue.main.async() { [weak self] in
                    WKInterfaceController.reloadRootControllers(
                        withNames: ["mainController"], contexts: [values]
                    )
                }

but then when I try to do the same in the main controller using

DispatchQueue.main.async() { [weak self] in
                    WKInterfaceController.reloadRootControllers(
                        withNames: ["loginController"], contexts: [message]
                )
}

the loginScreen gets displayed BUT the view controller from the main screen stays alive, keeps receiving Notifications from other objects and keeps spawning new loginControllers. I've already tried

    self?.pop()
    self?.dismiss()
    self?.popToRootController()
    self?.presentController(withName: 

none of which seem to deactivate the mainController. What can I do in this situation?

I do not need ANYTHING from the mainController as I will create a new one after successful login so how can I make sure to destroy the object entirely? I don't want to take care of all the references, listeners, timers, ... in the mainController which is why I am perfectly fine with destroying it.

Upvotes: 6

Views: 656

Answers (3)

Alexandru Motoc
Alexandru Motoc

Reputation: 704

This seems to be a relevant thread:

https://developer.apple.com/forums/thread/659778?answerId=654730022#654730022

Looks like the call to WKInterfaceController.reloadRootPageControllers is keeping the objects into memory, regardless of how you hold a reference to them (could be weak, etc.)

Upvotes: 0

Joey Slomowitz
Joey Slomowitz

Reputation: 189

Without seeing any of your code for the value you're trying to pass into the context, I would say that it's your context which is responsible for keeping some object in memory, which in turn is keeping your controller in memory. You can confirm this by checking the memory graph if you see NSMutableDictionary (Storage) holding onto the object that you're trying to pass around. - this is the context.

One messy solution is to just create an optional global var for whatever value you want to keep a reference to, and just assign it whatever value when needed and set it to nil when you want it deallocated. It's quite messy but it will solve your problem.

Upvotes: 0

Moose
Moose

Reputation: 2737

It's not easy to answer such question without having your main controller code. @kelin is probably right.

Have you tried to use the Memory Graph tool?

Debug Navigator -> Debug Area Separator -> The 3 connected circles icon

XCode Debug Area Separator

It gives you a state of the retains at a given time and can sometimes be. very helpful.

I would put a break in the login controller didAppear ( among other possibilities ) and inspect the graph.

Upvotes: 0

Related Questions