在 Modal View Controller 中使用 UINavigationController 进行内存管理

Posted

技术标签:

【中文标题】在 Modal View Controller 中使用 UINavigationController 进行内存管理【英文标题】:Memory Management with UINavigationController inside Modal View Controller 【发布时间】:2010-10-30 18:26:16 【问题描述】:

我正在尝试显示包含 NavigationController 的模态视图控制器。不过,我不知道在哪里释放控制器。通常,我会在显示控制器后将其释放,但这在这里行不通;大概这与导航控制器有关。任何帮助都会很棒!这是有问题的代码:

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

【问题讨论】:

【参考方案1】:

您正在自动释放 modalNavController 以及专门释放它,这就是导致它过早释放的原因。自动发布或专门发布,但尽量不要同时进行。

所以:

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

或专门发布所有内容:

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

【讨论】:

【参考方案2】:

“Controller”正在创建,并用作“rootViewController” - 但从未实际显示。因此,虽然它通常会被展示它的人保留 - 没有人这样做。

我对你为什么这样做有点困惑 - 但我猜是你的“控制器”版本导致了这个问题。

您可以通过在 modalNavController 消失之前不发布它来从技术上解决问题 - 但我不知道您为什么一开始就这样做。

【讨论】:

控制器正在由导航控制器 (modalNavController) 显示。她应该释放它。错误的出现是因为他既自动释放“modalNavController”又专门释放它(在他的评论部分)。这就是导致崩溃的原因。 谢谢!如果可能的话,我从不自动释放任何东西,所以我没有注意到我不小心把它放在那里!我本来可以找几个小时(我想我确实实际上已经找了几个小时了,但是......)但没有看到!

以上是关于在 Modal View Controller 中使用 UINavigationController 进行内存管理的主要内容,如果未能解决你的问题,请参考以下文章

使用 Modal View Controller -> ViewController 设置协议

present Modal View Controller:如何与父级交互

在 Modal 之后推送 UIView

iOS VC 推出另外一个背景透明的视图控制器(the content is displayed over another view controller’s content)

MVVM框架理解

Django