我最近改变了我的应用程序以使用UINavigationController,之前我使用的是UINavigationBar,添加了级联子视图,这有点过于简单。
我遇到了内存使用问题。泄漏工具没有显示任何泄漏,但我创建并添加到UINavigationController的ViewControllers似乎永远不会被释放。因此,每当我创建一个新的VC然后按下NavigationController的后退按钮时,内存使用量就会增加。
我只是以这种方式创建和添加我的VC:
DetailViewController* detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
// setups
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
该应用程序永远不会通过ViewController的dealloc
和viewDidUnload
方法。每次按下后退按钮都不应该调用它们吗?
我搜索了许多教程并阅读了Apple的内存管理,但是在使用NavigationController时,VC在内存中的生命周期并不存在。
答案 0 :(得分:5)
也许你没有做错事,而是面对像this
这样的事情在博客文章中,我们是否必须手动释放IBOutlets是一个问题。事实证明我们应该。这在iOS 3.1.3中是可重现的,但我还没有在iOS 4.0中测试它。
第二个方法是覆盖视图控制器保留和释放方法并打印出保留计数。我有一个类似的问题,一些视图控制器dealloc方法没有调用,所以我重写这个方法,看看有人仍然保留它。事实证明它确实如此。
修改强>
当我打印保留计数时,它有时会从框架中达到~98,因此不必担心。
如果你的最后一次保留计数保持在2并且不会调用dealloc方法,那么还有一个人仍然保留了它。
在这种情况下,您应该搜索其他地方。
例如我在同一个问题中遇到的另一个问题: 有时候我会用
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateUI) userInfo:nil repeats:YES]
不断更新UI。但我忘了的是,NSTimer将保留目标对象(它是ViewController)。因为NSTimer保留了您的视图控制器,所以永远不会调用dealloc,因为有人(NSTimer)仍然保留它。因此,您必须确保使NSTimer BEFORE dealloc方法无效以正确释放视图控制器。
编辑2以回复以下评论:
保留声明的属性如下(例如):
- (void)setTarget:(id)value {
if (value != target) {
[target release];
target = [value retain];
}
所以它首先发布你当前的self.target,然后保留新值。由于你指定的是nil,你的目标之后将是零。有关“属性”的更多信息,请参阅Apple文档。
答案 1 :(得分:2)
我也见过这个。正如你所指出的那样,我没有在文档中看到任何确定的内容,但我相信它们会被保留在内存中,直到需要内存为止。从性能角度来看,这是有道理的,因为这样做可以让应用程序在不同视图之间快速导航。
底线是,我不担心。您可以在模拟器中触发一些低内存警告,看看它是否实际释放了您的VC。