【问题标题】:Memory management with pushViewController使用 pushViewController 进行内存管理
【发布时间】:2011-08-22 09:34:24
【问题描述】:

我仍然对内存管理技术不太了解,想知道是否有人可以向我解释这种奇怪的行为。考虑一下我一直在测试的这 3 段代码:

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
NSLog(@"dof retain count = %d", [dofView retainCount]); 

此日志:保留计数 = 1。这很好。

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
[dofView release];
NSLog(@"dof retain count = %d", [dofView retainCount]); 

这个日志:retain count = 1。不应该是0吗??

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
[self.navigationController pushViewController:dofView animated:YES];
NSLog(@"dof retian count = %d", [dofView retainCount]);

这个日志:retain count = 5。我不知道为什么是 5 个?

任何人都可以对此有所了解吗?我担心每次创建新视图时都会占用内存。

谢谢!

【问题讨论】:

  • retainCount 永远不能返回 0

标签: iphone ios memory-management pushviewcontroller


【解决方案1】:

不要依赖retainCount 进行内存分析。查看Memory Management 上的参考文档以获取更多信息

【讨论】:

    【解决方案2】:

    强烈建议不要查看保留计数,它不会为您提供任何有价值的信息。如果你想知道某些东西是否被正确释放,你应该在你的类的 dealloc 方法中放置一个断点或一个日志条目——当调用 dealloc 时,该对象很快就会被释放。除了工具应用程序之外,这是我用来查找保留周期的工具。

    【讨论】:

      【解决方案3】:

      When to use -retainCount?

      retaincount 好像没用

      【讨论】:

      • 你不使用它 - NSObject 会:)
      【解决方案4】:

      知道立即释放很重要(自动释放需要一段时间)。

      那么为什么您的对象的保留计数仍然为 1?

      因为它已被释放 - 它不再是你的对象,它只是一些空闲内存!

      尝试这样做:

      NSObject* o = [[NSObject alloc] init];
      NSLog(@"retain count = %d", [o retainCount]); 
      [o retain];
      NSLog(@"retain count = %d", [o retainCount]); 
      [o release];
      NSLog(@"retain count = %d", [o retainCount]); 
      [o release];
      NSLog(@"retain count = %d", [o retainCount]); 
      

      你得到输出

      retain count = 1
      retain count = 2
      retain count = 1
      retain count = 1
      

      您可能希望最后一行显示 0,而不是 1。但是,如果要释放它,它不会减少保留计数 - 这有什么意义!

      实际上,最后一行输出任何内容而不会崩溃这一事实是幸运的——因为对象已被释放,没有什么能阻止内存被其他东西使用——它现在实际上只是随机数据。这正是导致 EXC_BAD_ACCESS 崩溃的错误 :)

      事实上,您会在最终的NSLog 上收到编译器分析器警告,因为您将消息传递给不再存在的对象:)


      至于 5 的保留计数-我只能回应其他答案-您不知道对象内部发生了什么-仅仅因为您只调用了一次保留并不意味着没有其他人调用保留:)

      只要你为每一次保留释放,你就做对了。

      如果您担心泄漏,请使用分析器并检查!

      【讨论】:

      • 我会说最后一个NSLog 语句是一个编程错误。一旦释放对象引用,您就应该永远不要访问它。释放一个对象是明确说明; 我已经完成了这个对象,不再需要它了。最后的NSLog 声明可以并且将导致道路上的崩溃。一个好的提示是始终nil 退出您发布的任何对象,[obj release], obj = nil; 是一种很好且明确的方式。
      • @PeyloW - 这正是我的观点 - 出现意外答案的原因是 这是错误的
      • @deanWormbourne - 我只想指出,我认为重要的是要强调结果可能不仅是错误的答案,而且是崩溃。因此,即使出于调试/测试目的,这样的代码也不会留在应用程序中。
      • 是的,我已经更新了我的答案以包含一段警告它可能会崩溃:)
      【解决方案5】:

      retainCount 属性取决于 UINavigationController 如何处理您正在推送的控制器。如果它在 UIViewController 对象中多次保留,您不必担心。重要的是当使用那个对象时,当你不再需要它时释放它。

      例如在这种情况下,由于您将新控制器推送到导航器,您应该这样做:

      DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
      [self.navigationController pushViewController:dofView animated:YES];
      [dofView release];
      

      对象的保留计数可能不会立即更新,因此您不应该真正关心该计数。

      如果你认为你正在泄漏内存,你应该使用 Xcode 中的分析工具(搜索内存泄漏)。

      希望这会有所帮助。

      【讨论】:

        【解决方案6】:

        不要依赖保留计数。过去我也尝试检查内存管理的保留计数,但它总是让我感到困惑(当保留计数让我感到困惑时,请查看此链接 [http://stackoverflow.com/q/5483357/644149]。只需遵循简单的指南,然后你会你的应用没有内存泄漏

        当你使用 alloc、new、copy、retain 时,你也应该释放那个对象。简单

        【讨论】:

          【解决方案7】:

          release 调用不会立即生效,因此保留计数可能看起来不正确。您可以使用 Leaks 工具来跟踪内存问题,但只要您遵循内存管理规则,通常应该没问题。

          【讨论】:

          • 发布立即生效。自动释放需要一段时间才能发生。 retainCount 看起来不正确的原因是因为您不知道对象/框架内部发生了什么。 - 它可能会被其他东西保留。
          猜你喜欢
          • 2013-08-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-30
          相关资源
          最近更新 更多