仪器显示内存泄漏 – Xcode 5 / iOS7

我有以下一段代码:

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]; 

在上面的代码中,仪器在第二行显示100%的内存泄漏,在xcode 4.6中情况并非如此。 我正在使用osx 10.8.5上的xCode 5

看来,我正确地释放分配的UIImageView (第7行),它被插入我的观点在第6行,所以我不明白为什么intruments提出了内存泄漏警告。

有人知道为什么仪器会提出(在我看来)错误的信息?

编辑:这是仪器 – 截图与我的泄漏对象的分配总结:

仪器 - 分配

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

UIImageView被插入到在我的xib文件中引用的视图(一个UIViewController )。 在添加到'self.view'后,如何控制添加的UIImageView会发生什么?

我在iOS 7上遇到了与Xcode 5相同的问题。经过一些实验,我注意到Instruments在运行iOS 6.1模拟器或运行iOS 7的设备(iPhone 5s)上运行时不会显示mem泄漏。基于这些,我只能得出这样的结论:这是iOS 7模拟器中的误报和错误。

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

仪器显示触发分配泄漏对象的代码行,而不是为什么对象实际上泄漏。 打开引用计数跟踪并查看该图像视图上的所有保留/释放事件。 会有一个额外的保留(或丢失的版本)。

我注意到这是发生在你的RootViewController实例上。 这真的是顶级视图控制器(例如,你永远不会解雇/stream行)? 如果是这样,这个分配总结正确地告诉你,图像视图仍然存在,它很奇怪,它被报告为泄漏。

如果视图控制器已被解雇,那么你有一个真正的泄漏(虽然问题不在于你的问题的代码中:你已经做到了这一点)。 你的分配总结certificate你的UIImageView永远不会被破坏。 如果视图控制器被正确解除和释放,那么图像视图的“分配摘要”应该如下所示:

分配摘要

请注意,当我popup视图控制器(在我的分析会话28秒),视图得到释放,因此UIImageView也(见两个突出显示的行)。

您可以从您的分配汇总中得出两个结论:

  • 它不显示任何其他保留在你的UIImageViewbuild议这个图像视图不是问题。 不是你不小心过度保留了这个图像视图。

  • 事实上,你没有看到removeFromSuperview ,表明你的superview本身,永远不会被释放。

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

顺便说一句,这听起来像你已经熟悉这些主题,但我经常引用人们WWDC 2012videoiOS应用程序性能:内存 ,它不仅描述了许多内存问题,而且还演示了使用仪器来跟踪这些(如显着的heapshots)。

我开始有相同的问题,我正在寻找imageNamed。 我发现过去有记忆问题。 我终于最终使用[[UIImage alloc] initWithContentsOfFile:actualPath],其中actualPath来自主包。

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

我testing和是的UIImageView setImage确实泄漏!

如果你通过一堆图像循环

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

你可以在仪器上看到内存使用量的增加。 这似乎是某种caching四处走动后,通过所有的图像循环内存使用将会持平。

正确的或者至less是不漏的方式是:

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

我在我的代码上validation了这一点,因为我的应用程序正在循环大量的大图像文件。

只是一个build议。 不要在模拟器上运行仪器。 在设备上执行。 有很多不同,你会看到更好/相关的结果。 例如。 模拟器比真实设备有更多的内存。