0
votes

I have a UIViewController that is popped from the navigation stack on iPhone and removed by setRootViewController on the iPad.

In both cases the UIViewController fails to dealloc, which means that something is hanging on to it; this is confirmed by logging [self retainCount] which is two, right before the pop or the setRootViewController (for some reason it's four in ViewWillDisappear).

The UIView has audio (using Flite Text to Speech - which uses AVFoundation.framework) and animation.

What things should I look for that could increasing my retain count in the view controller and stopping the view controller from being politely dealloced as it should be.

Here's how the view is pushed onto the view stack or set as the RootViewController;

-(IBAction)pushShare:(id)sender{

    ShareViewController *shareViewController =  [[ShareViewController alloc] initWithNibName:@"ShareViewController" bundle:nil];
    NSLog(@"1. SVC Retain count %d", [shareViewController retainCount]);
    [shareViewController setParentIsIpadMake:YES];
    NSLog(@"2. SVC Retain count %d", [shareViewController retainCount]);    
    [shareViewController setStory:story];
    NSLog(@"3. SVC Retain count %d", [shareViewController retainCount]);      
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {      
        StoryBotAppDelegate *appDelegate = (StoryBotAppDelegate *)[[UIApplication sharedApplication] delegate];
        [appDelegate.window setRootViewController:shareViewController];
        NSLog(@"4. SVC Retain count %d", [shareViewController retainCount]);      
    } else{


        [self.navigationController pushViewController:shareViewController animated:YES];
        NSLog(@"4. SVC Retain count %d", [shareViewController retainCount]);      

    }

    NSLog(@"releasing Svc...");
    [shareViewController release];
    NSLog(@"5. SVC Retain count %d", [shareViewController retainCount]);

}
3
How is it created and pushed on the navigation stack? - Kris Van Bael
I've updated the question for you @KrisVanBael - glenstorey
Also, how do you know it isn't dealloc'ed ? It is possible that your view controller is dealloc'ed. In which case the memory is freed up for other things and asking for its retain count can basically return anything. - Kris Van Bael
I have a NSLog in dealloc which isn't logging - glenstorey

3 Answers

1
votes

First, try running Xcode's static analyser, it may find what is wrong.

You can also try overriding retain method with calling [super retain] and logging. Moreover you can put a breakpoint there and look at the stack when Xcode stops on it.

Or you can run ARC conversion tool and see what happens.

1
votes

Retain count method is next to useless. The system libraries will be retaining your VC and releasing it. Which is why sometimes it will be a strangely high number. There are lots of topics on this.

Don't be concerned about the view animation delegate having the VC. The view and the VC are intimately tied together and released together, and the view doesn't retain its animation delegate - it just assigns it as a reference.

If u are testing in the simulator, force a memory warning and see if it is dealloc'ed. Dealloc'ed isn't always called immediately when you pop the VC.

Run instruments leaks. Does it say the VC is leaking memory? Run instruments with Zombies to find out whe it is leaking.

0
votes

I read this question about NSTimer stopping the dealloc of a UIView. Turns out I had a NSTimer firing my animations which was stopping dealloc from happening nicely. I fixed it by adding a method called killTimer:

-(void)killTimer{
    [animationTimer invalidate];
    animationTimer = nil;
}

which I called on closing the view.

Thanks heaps for the answers to this question though - they were super helpful. I didn't actually know about the static analyzer until asking - or about how useless retain counts are; so +1 to you both.