Reputation: 153
I can't figure out why FirsViewController is not destroyed/releasedd in this scenario.
My AppDelegate.m - FirstViewController is pushed on the stack
self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
self.navigationController = [[UINavigationController alloc]init];
self.FirstViewController = [[FirstViewController alloc]
initWithNibName:@"FirstViewController"
bundle:[NSBundle mainBundle]];
[self.navigationController FirstViewController animated:YES];
FirstViewController.m
self.SecondViewController = [[SecondViewController alloc]
initWithNibName:@"SecondViewController"
bundle:[NSBundle mainBundle]];
self.SecondViewController.totalNumberOfPlayers = self.selectedRow;
[self.navigationController pushFadeViewController:self.SecondViewController];
[self.view removeFromSuperview];
-(void)dealloc
{
[SecondViewController release];
NSLog(@"SecondViewController released");
}
When I run the app and switch from first to second view controller there is no NSLog input in console. This makes me think that the first view controller is not destroyed and the memory for it is not released.
Seems like [self.view removeFromSuperview] is not working well in this situation.
My question is how to release/destroy the FirstController ? It will be never used at the rest of the app.
Upvotes: 3
Views: 10782
Reputation: 40995
You are correct that view controllers in the stack are not released/destroyed. This is not a bug - it's by design because if you pop your current view controller it would need to display the underlying one again. The app doesn't know that you never intend to do that.
Your [self.view removeFromSuperview] doesn't work because that removes the view from the window (which has already been removed anyway when you pushed your second view controller) not the view controller from the stack (I think you may be confusing your views and your view controllers).
If you want to get rid of the first view controller, when you push your second view controller, instead of calling:
[navigationController pushViewController:secondViewController animated:YES];
Call this instead:
[navigationController setViewControllers:[NSArray arrayWithObject:secondViewController] animated:YES];
That will replace the first view controller completely instead of just pushing the new one on top of it. The animation will be the same.
Be warned that the first view controller will be released immediately when you call the method above, so don't try to do anything to the first view controller after calling this or there's a good chance it will crash.
Update:
Here's how your app delegate setup code should look:
self.window = [[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.navigationController = [[[UINavigationController alloc] init] autorelease];
FirstViewController *firstViewController = [[FirstViewController alloc] init];
[self.navigationController pushViewController:firstViewController animated:YES];
[firstViewController release];
Things to note:
Don't store the firstViewController in a property, or it won't be released when it's popped and dealloc still won't get called (you can delete the firstViewController) property.
Use lowercase for variable names, only capitalize class names
Always release or autorelease objects that you alloc/init in the same method where you create them - this will avoid Analyzer warnings (and avoid leaks).
You don't need to specify the nib file if the nib file name matches the view controller class name.
Nick
Upvotes: 16