Search code examples
xcodeperformselector

performSelector afterdelay still running even though I have unloaded the viewcontroller that it originated from


In Xcode I have a view which does a modal segue to tab bar controller, and the first view in the tab bar is a UIViewController. This view performs a task on a timed basis (every 15 seconds) using [self performSelector:@selector(blah:) withObject:nil afterDelay:15]. I have some delegate methods that take me back to the root view and calls [self dismissViewControllerAnimated] which in my mind would unload the tab bar controller which would in turn unload the view that is performing the selector every 15 seconds. While those views do disappear after I call dismissViewControllerAnimated, the selectors continue to run every 15 seconds (I see them logging messages in the Xcode console). Am I wrong in my logic that these selectors should cease since their viewcontroller has been unloaded?


Solution

  • Not always. It depends on your classes, if you have a strong reference to the controller or the timer somewhere it may not actually be released. It could also be that since the timer was never invalidated it's keeping the view controller from releasing. Timers are interesting in that they can cause behavior like this if not invalidated, it's always good practice to clean them up when you're done with them. If you're using recursion to call the timed method on itself every 15 seconds that could also keep the view from being released.

    If you're using a timer you'll want to invalidate it when appropriate, on view disappear probably. If you want to run once after view disappear you'll need to set a bool so you know when the view disappeared so you can run it once more.

    If you're using recursion, be really careful. Something like that can run on a background thread indefinitely. Again if you only want it to run while the view is the active view you can do a check to see which view is on top and only call the method recursively in that scenario, or set a bool on appear and disappear and check the bool when the method calls itself.