【问题标题】:Instruments show memory leak - Xcode 5 / iOS7仪器显示内存泄漏 - Xcode 5 / iOS7
【发布时间】:2013-09-26 13:46:33
【问题描述】:

我有以下代码:

NSString *bgImageName = [[Useful instance] getRootviewBackgroundImageName];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:bgImageName]];
imageView.clipsToBounds = YES;
CGRect rc = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[imageView setFrame:rc];
[self.view insertSubview:imageView atIndex:0];
[imageView release];

Instruments 在上述代码的第二行显示 100% 和内存泄漏,而在 xcode 4.6 中并非如此。我现在在 osx 10.8.5 上使用 xCode 5

看来,我正确释放了分配的 UIImageView(第 7 行),它在第 6 行插入到我的视图中,所以我看不出为什么仪器会发出内存泄漏警告。

有人知道为什么仪器会显示(在我看来)错误信息吗?

编辑:这是带有我的泄漏对象的分配摘要的仪器屏幕截图:

UIKit 和 QuartzCore 保留了我的对象,这就是我泄漏 UIImageView 的原因(或者我对这个假设有误?)。

UIImageView 被插入到我的 xib 文件中引用的视图(UIViewController)中。将我添加的UIImageView 添加到“self.view”后如何控制它会发生什么?

【问题讨论】:

  • 什么对象被泄露了?
  • “UIImageView”对象
  • 我有类似的东西,我看到它只发生在模拟器 [imageview setImage:[UIImage imageNamed:@"img-568h@2x"]]; (在这里泄漏)我正在使用 arc xcode 5 ios 7
  • @dave 只有在针对 iOS 7 使用模拟器进行分析时才会出现泄漏。使用设备或模拟器针对所有 iOS 版本进行分析永远不会出现任何内存泄漏警告(请参阅 Dan Marinescu 的回答)

标签: ios objective-c xcode instruments


【解决方案1】:

我在 iOS 7 上使用 Xcode 5 时遇到了同样的问题。经过一些实验后,我注意到 Instruments 在针对 iOS 6.1 模拟器或针对运行 iOS 7 的设备 (iPhone 5s) 运行时没有显示内存泄漏。基于这些我只能得出结论,这是一个误报,是 iOS 7 模拟器中的一个错误。

编辑:在我更新到 Xcode 5.0.1 和 OS X Mavericks 后,此问题不再发生(我猜这是第一个修复它但无法确定的问题)。

【讨论】:

  • 我也想通了。现在将提交我的应用程序:) 感谢大家的帮助!
【解决方案2】:

Instruments 显示了触发泄漏对象分配的代码行,以及不是对象实际泄漏的原因。打开引用计数跟踪并查看该图像视图上的所有保留/释放事件。会有额外的保留(或缺失的版本)。

【讨论】:

  • 感谢您的帮助,但我仍然无法摆脱仪器中的泄漏对象。请看看我编辑的问题。
【解决方案3】:

我注意到这发生在您的 RootViewController 实例上。这真的是顶级视图控制器(例如,您永远不会关闭/弹出的视图控制器)吗?如果是这样,则此分配摘要正确地告诉您图像视图仍然存在,并且奇怪的是它被报告为泄漏。

但是,如果视图控制器已被解除,那么您就有了真正的泄漏(尽管问题不在于您问题中的代码:您已经正确地做到了)。您的分配摘要证明您的UIImageView 永远不会被破坏。如果视图控制器被正确解除和释放,图像视图的分配摘要应该如下所示:

请注意,当我弹出视图控制器时(在我的 Profiling 会话中 28 秒),视图正在被释放,因此 UIImageView 也是如此(参见突出显示的两条线)。

您可以从分配摘要中得出两个结论:

  • UIImageView 上没有显示任何其他保留,这表明此图像视图根本不是问题。这不是您不小心在某处过度保留此图像视图的情况。

  • 您看不到removeFromSuperview 的事实表明您的superview 本身永远不会被释放。

所以,问题是您的RootViewController 是否已从视图控制器层次结构中删除。如果是这样,那么你有一个泄漏或保留周期,可能是视图控制器本身,而不是这个图像视图。

顺便说一句,听起来你对这些话题已经很熟悉了,但我经常向人们介绍 WWDC 2012 视频iOS App Performance: Memory,它不仅描述了许多内存问题,还演示了使用 Instruments 来跟踪这些问题下降(例如显着的堆)。

【讨论】:

    【解决方案4】:

    我开始遇到同样的问题,我正在研究 imageNamed。我发现过去存在内存问题。我最终使用了 [[UIImage alloc] initWithContentsOfFile:actualPath] ,其中 actualPath 来自主包。

    【讨论】:

      【解决方案5】:

      我认为@mishod 的答案是正确的。

      我测试过,是的 UIImageView setImage 确实泄漏了!

      如果你循环浏览一堆图片

         [yourImageView setImage:[UIImage imageNamed:@"sampleImage.png"]];
      

      您可以看到仪器的内存使用量在增加。 从那以后,这似乎是某种缓存 循环浏览所有图像的内存使用量将持平。

      正确的,或者至少是不泄漏的方法是:

         NSString *thePath = [[NSBundle mainBundle] pathForResource:@"sampleImage" ofType:@"png"];
         UIImage *newImage =  [[UIImage alloc] initWithContentsOfFile:thePath];
         [yourImageView setImage:newImage];
      

      我在我的代码上验证了这一点,因为我的 APP 循环了很多次 大图像文件。

      【讨论】:

        【解决方案6】:

        只是一个建议。不要在模拟器上运行 Instruments。在设备上进行。有很多差异,您会看到更好/相关的结果。例如。模拟器拥有比真实设备更多的内存。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-07
          • 2012-04-03
          • 2011-10-10
          • 2018-09-27
          • 2014-11-16
          • 2012-07-06
          • 2011-02-15
          • 2010-11-26
          相关资源
          最近更新 更多