【问题标题】:UINavigationController and UIViewController deallocUINavigationController 和 UIViewController 解除分配
【发布时间】:2010-07-12 16:25:44
【问题描述】:

我最近将我的应用程序更改为使用 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在内存中的生命周期一无所获。

【问题讨论】:

  • Jukurrpa,您解决了这个问题吗?我面临着同样困扰我的问题。

标签: iphone memory uiviewcontroller uinavigationcontroller dealloc


【解决方案1】:

也许您并没有做错什么,而是您面临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]

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

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

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

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

【讨论】:

  • 好吧,我确实在 dealloc 方法中释放了每个出口。但它没有任何效果,因为它从未被调用过。我试图覆盖释放和保留,除了在某些时候retainCount 达到50+(由子视图引起?)它在最后一次发布后保持为2(当我离开视图时)。我不明白为什么会这样,因为我只在我发布的代码中使用它。
  • 这帮助我修复了剩余的保留之一,谢谢。我没有使用 NSTimer,但我使用了 ASIHTTPRequest 的包装器,它以 DetailViewController 作为某些操作的代表。我只需要在调用 DetailVC viewDidDisappear 时释放它。可能最后的retain也是因为这个原因,我会继续寻找。
  • 我刚刚通过在我之前谈到的包装器中释放它之后添加“self.target = nil”来修复第二个剩余的保留。 (目标是 DetailVC,存储为具有保留属性的 id)。什么可以解释这一点?
  • 嗯,事实上这似乎不是解决方案。当我离开视图时,这会随机导致崩溃......该死的内存管理。自动/共享指针不会更简单吗? :(
  • HTTPRequest 听起来像是在使用某种异步操作?如果是这种情况,您还应该知道,当您在请求完成时调用目标选择器时,您的目标可能刚刚被释放(可能通过关闭视图)并且您的应用程序将崩溃,因为您正在调用某个释放对象。
【解决方案2】:

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

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

【讨论】:

  • 感谢您的回答。在创建并留下大约 10 个 VC 后,我刚刚尝试在模拟器中发送内存不足警告。调用了所有 VC 的 viewDidUnload 方法,但根本没有 dealloc!而且,根据它们在内存中的地址,似乎没有一个被重用,因此内存使用量越来越大。
  • 我建议看看苹果开发者论坛。您可以从一位 Apple DTS 版主那里找到更详细的答案。
  • 我没上过这个论坛,我看看,谢谢。
猜你喜欢
  • 2011-02-20
  • 2012-02-07
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-13
相关资源
最近更新 更多