Search code examples
iosuinavigationcontrollerpopviewcontrolleranimated

UINavigationController doesn't release/destroy controllers after popViewControllerAnimated?


During past few days I'm trying to investigate very strange situation I've recently discovered. The thing is that pushed controller looks staying alive after popViewControllerAnimated: call. I've created simple test project (ARC enabled) with two controllers embedded within root navigation controller and the behaviour has been reproduced. enter image description here Here is first viewController code fireing second controller:

-(IBAction)push:(id)sender {
    [self performSegueWithIdentifier:@"vseg" sender:nil];
}

nothing unusual from my perpective. there is a method in second controller which is called by timer each second:

-(void) ticker {
    NSLog(@"from ViewController2 %d", tickerCount++);
    _counterLabel.text = [NSString stringWithFormat:@"tick: %d", tickerCount];
    [self performSelector:@selector(ticker) withObject:nil afterDelay:1];
}

still nothing unusual - the app works as expected, UILabel updates with incremented tickerCount value and messages appear on console. Next we tap Back button, first controller is popped and console continues receive messages from second controller. enter image description here

I'm still with no idea what does it actually mean? Wheter the entire controller stays unreleased or just ticker method held by some clousure variable which doesn't make sence to me. Here is test project http://hxml.ru/EliEX


Solution

  • to cancel the selector just use

    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    

    or

    [NSObject cancelPreviousPerformRequestsWithTarget:selector:object:]
    

    The target is the original object on which performSelector:afterDelay: was called

    - (void)viewWillDisappear:(BOOL)animated
    {
       [NSObject cancelPreviousPerformRequestsWithTarget:self];
    }
    

    refer Run Loops and NSObject docs