简体   繁体   中英

Memory Management with UINavigationController inside Modal View Controller

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.
}

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];

"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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM