2

我有以下代码:

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在第 6 行插入到我的视图中的已分配(第 7 行),所以我看不出为什么仪器会发出内存泄漏警告。

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

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

工具 - 分配

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

UIImageView插入到UIViewController我的 xib 文件中引用的视图 (a) 中。UIImageView将其添加到“self.view”后如何控制我添加的内容?

4

6 回答 6

5

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

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

于 2013-10-21T09:17:29.517 回答
1

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

于 2013-09-26T15:21:28.300 回答
1

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

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

分配摘要

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

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

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

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

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

顺便说一句,听起来你对这些话题已经很熟悉了,但我经常参考 WWDC 2012 视频iOS App Performance: Memory,它不仅描述了许多内存问题,还演示了使用 Instruments 来跟踪这些问题(例如特别是heapshots)。

于 2013-09-27T14:52:22.983 回答
1

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

于 2013-10-13T21:52:01.487 回答
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 正在循环浏览大量大图像文件。

于 2013-11-06T12:55:21.453 回答
1

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

于 2014-09-28T01:10:19.073 回答