views:

35

answers:

2

Hi all, I am trying to display a modal view controller containing a NavigationController. I can't figure out where to release the controllers, though. Normally, I would just release the controller after displaying it, but that won't work here; presumably that has something to do with the navigation controller. Any help would be great! Here is the code in question:

-(IBAction)displayCreateModifyExerciseViewController:(id)sender {    
    CreateModifyExerciseViewController *controller = [[CreateModifyExerciseViewController alloc] initWithNibName:@"CreateModifyExerciseView"
                                                                                                          bundle:nil];
    controller.delegate = self;
    controller.title = @"Create Exercise";
    UINavigationController *modalNavController = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease];
    modalNavController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    controller.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Save"
                                                                                    style:UIBarButtonItemStyleDone
                                                                                   target:controller
                                                                                   action:@selector(done:)];
    [self presentModalViewController:modalNavController animated:YES];
    //I want to say [controller release];
    //              [modalNavController release];
    //But that causes a crash because controller ends up dealloc-ing.
}
A: 

"Controller" is being created, and used as the "rootViewController" - but is never actually displayed. Thus, while it would normally be retained by whoever is displaying it - no one has done that.

I'm a little confused on why your doing this - but I'm guessing it is your release of "controller" that is causing the issue.

You could technically fix the issue by not releasing it until modalNavController has gone away - but I don't know why you are even doing that in the first place.

Brad
Controller is being displayed by the navigation controller (modalNavController). She should release it. The error comes because he both autoreleases 'modalNavController' as well as specifically releasing it (in his commented section). That is what causes the crash.
Jason Coco
You're correct!
Brad
Thanks! I never autorelease anything, if possible, so I didn't notice that I accidentally put it in there! I could have looked for hours (I guess I *did* actually already look for hours, but...) and not seen that!
+1  A: 

You are auto releasing modalNavController as well as specifically releasing it, which is what's causing it to dealloc prematurely. Either auto-release or specifically release, but try not to do both at the same time.

So:

CreateModifyExerciseViewController *controller = [[[CreateModifyExerciseViewController alloc] initWithNibName:@"CreateModifyExerciseView" bundle:nil] autorelease];
controller.delegate = self;
controller.title = @"Create Exercise";
UINavigationController *modalNavController = [[[UINavigationController alloc] initWithRootViewController:controller] autorelease]; // <-- you originally autorelease here
modalNavController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
controller.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] 
                         initWithTitle:@"Save" 
                                 style:UIBarButtonItemStyleDone
                                target:controller
                                action:@selector(done:)] autorelease]; // <-- this was leaking in your code -- needs to be autoreleased
[self presentModalViewController:modalNavController animated:YES];
// Don't release now because everything was autoreleased

OR specifically release everything:

CreateModifyExerciseViewController *controller = [[CreateModifyExerciseViewController alloc] initWithNibName:@"CreateModifyExerciseView" bundle:nil];
controller.delegate = self;
controller.title = @"Create Exercise";
UINavigationController *modalNavController = [[UINavigationController alloc] initWithRootViewController:controller]; // <-- you originally autorelease here
modalNavController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
controller.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] 
                         initWithTitle:@"Save" 
                                 style:UIBarButtonItemStyleDone
                                target:controller
                                action:@selector(done:)] autorelease]; // <-- this was leaking in your code -- needs to be autoreleased
[self presentModalViewController:modalNavController animated:YES];
// Now we specifically release the controllers because the call to -presentModalViewController:animated: owns them
[controller release];
[modalNavController release];
Jason Coco