3

我最近更改了我的应用程序以使用 UINavigationController,我之前使用的是 UINavigationBar,添加了级联子视图,这有点脆弱。

我面临内存使用问题。泄漏工具没有显示任何泄漏,但我创建并添加到 UINavigationController 的 ViewController 似乎从未被释放。因此,每次我创建一个新的 VC 然后按下 NavigationController 的后退按钮时,内存使用量都会增加。

我只是这样创建和添加我的 VC:

DetailViewController* detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
// setups
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];

该应用程序从不通过 ViewController 的deallocviewDidUnload方法。每次我按下后退按钮时不应该调用这些吗?

我搜索了很多教程并阅读了 Apple 的内存管理,但是在使用 NavigationController 时,VC 在内存中的生命周期一无所获。

4

2 回答 2

5

也许你没有做错什么,而是你面临着这样的事情

在博客文章中,问题是我们是否必须手动释放 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]

不断更新用户界面。但我忘记的是,NSTimer 将保留目标对象(即 ViewController)。因为 NSTimer 保留了您的视图控制器,所以您的 dealloc 将永远不会被调用,因为有人(NSTimer)仍然保留在它上面。因此,您必须确保在 dealloc 方法之前使 NSTimer 无效,以正确释放视图控制器。

Edit2 回应以下评论:
保留声明的属性如下(示例):

- (void)setTarget:(id)value {
  if (value != target) { 
    [target release];
    target = [value retain];
}

所以它确实首先释放您当前的 self.target 然后保留新值。由于您分配 nil,因此您的目标之后将为零。有关属性的更多信息可以在 Apple 文档中找到。

于 2010-07-13T10:02:49.397 回答
2

我也看到了这一点。正如您所指出的,我在文档中没有看到任何明确的内容,但我相信它们会保留在内存中,直到需要内存为止。从性能的角度来看这是有道理的,因为这样做可以让应用程序在不同的视图之间快速导航。

底线是,我不会担心它。您可以在模拟器中触发一些内存不足警告,看看它是否真的释放了您的 VC。

于 2010-07-12T16:32:13.717 回答