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

时间:2013-09-26 13:46:33

标签: ios objective-c xcode instruments

我有以下代码:

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%和第2行的内存泄漏,而在xcode 4.6中并非如此。我现在正在使用osx 10.8.5上的xCode 5

看来,我正确地释放了在第6行的视图中插入的已分配UIImageView(第7行),所以我无法看到为什么intruments会引发内存泄漏警告。

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

编辑:这是仪器截图,其中包含我泄漏对象的分配摘要:

Instruments - Allocations

UIKit和QuartzCore正在保留我的对象,这是我泄漏UIImageView的原因(或者我错误地认为这个假设?)。

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

6 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

如果视图控制器已被解雇,那么你有一个真正的泄漏(虽然问题不在你的问题的代码中:你已经正确地完成了)。您的分配摘要证明您的UIImageView永远不会被破坏。如果视图控制器被正确解除并取消分配,则图像视图的分配摘要应如下所示:

Allocations Summary

注意,当我弹出视图控制器(在我的性能分析会话中为28秒)时,视图将被取消分配,因此UIImageView也是(请参见两个突出显示的行)。

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

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

  • 您没有看到removeFromSuperview,这表明您的superview本身永远不会被取消分配。

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

顺便说一句,听起来你已经熟悉了这些主题,但我经常将人们引荐到WWDC 2012视频iOS App Performance: Memory,这不仅描述了许多内存问题,而且还演示了如何使用跟踪这些(例如特别是快照)。

答案 3 :(得分:1)

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

答案 4 :(得分:1)

我认为@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正在循环很多 大图像文件。

答案 5 :(得分:1)

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