【发布时间】:2015-03-23 17:50:21
【问题描述】:
在子视图中显示和关闭 UINavigationController 时,我遇到了内存泄漏(UINavigationController 及其根视图控制器都被泄漏)。我展示导航控制器的方法似乎有点不标准,所以我希望 SO 社区中的某个人能够提供帮助。
1.演示文稿
导航控制器如下所示:
-(void) presentSubNavigationControllerWithRootViewControllerIdentifier:(NSString *)rootViewControllerIdentifier inStoryboardWithName:(NSString *)storyboardName {
// grab the root view controller from a storyboard
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
UIViewController * rootViewController = [storyboard instantiateViewControllerWithIdentifier:rootViewControllerIdentifier];
// instantiate the navigation controller
UINavigationController * nc = [[UINavigationController alloc] initWithRootViewController:rootViewController];
// perform some layout configuration that should be inconsequential to memory management (right?)
[nc setNavigationBarHidden:YES];
[nc setEdgesForExtendedLayout:UIRectEdgeLeft | UIRectEdgeRight | UIRectEdgeBottom];
nc.view.frame = _navControllerParentView.bounds;
// install the navigation controller (_navControllerParentView is a persisted IBOutlet)
[_navControllerParentView addSubview:nc.view];
// strong reference for easy access
[self setSubNavigationController:nc];
}
此时,我的期望是导航控制器的唯一“所有者”是父视图控制器(在本例中为self)。但是,当如下所示关闭导航控制器时,它并没有被释放(因此它的rootViewController 也被泄露,依此类推,沿着所有权树向下)。
2。解雇
Dismissal 非常简单,但似乎不足以进行适当的内存管理:
-(void) dismissSubNavigationController {
// prevent an orphan view from remaining in the view hierarchy
[_subNavigationController.view removeFromSuperview];
// release our reference to the navigation controller
[self setSubNavigationController:nil];
}
肯定有其他东西在“保留”导航控制器,因为它没有被释放。我不认为它可能是根视图控制器保留它,不是吗?
一些研究表明retainCount 毫无意义,但我确定它在解雇后仍保持在 2,我预计它会为零。
是否有完全不同/更好的方法来呈现 subNavigationController?也许在故事板中定义导航控制器比简单地消除对几行代码的需要有更大的好处?
【问题讨论】:
标签: ios objective-c memory-leaks uinavigationcontroller