在 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:如何与父级交互
iOS VC 推出另外一个背景透明的视图控制器(the content is displayed over another view controller’s content)