加载 UIImage 时 iOS 应用程序崩溃(虚拟内存未清理)
Posted
技术标签:
【中文标题】加载 UIImage 时 iOS 应用程序崩溃(虚拟内存未清理)【英文标题】:iOS Application Crash while UIImage loading (virtual memory not cleaning up) 【发布时间】:2013-05-29 04:52:16 【问题描述】:我的应用程序发生了奇怪的崩溃,没有任何痕迹。这可能是与内存相关的问题,但信息很少,我不确定如何继续或修复它。如果不是因为乐器,就永远不知道是什么了。
我有一个图像数组(在此示例中为大小为 2 的数组),我在其中加载图像,创建图像上下文并绘制并将其保存到数组中。每次调用该方法时,图像数组对象都会被新内容替换。在仪器中,我在此方法调用期间看到非常巨大的虚拟内存使用量,显然在每次调用内存未清除之后,因此崩溃。该项目是ARC。我将在下面列出代码。这就是我们重新创建此问题所需的全部内容。 (我使用的图像大小约为 7MB,因此更容易重新创建崩溃)。我也在使用 iPad2 设备。
+ (UIImage *)imageCopy:(UIImage *)src
UIGraphicsBeginImageContext(src.size);
[src drawAtPoint:CGPointZero];
UIImage *r = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return r;
- (IBAction)buttonTouch:(id)sender
for (int i=0; i<2; i++)
if (i==0)
self.mImage = [UIImage imageNamed:@"LARGE_elevation.jpg"];
else
self.mImage = [UIImage imageNamed:@"LARGE_elevation2.jpg"];
// imageArray is a NSMutableArray with capacity of 2
[imageArray setObject:[ViewController imageCopy:self.mImage] atIndexedSubscript:i];
((UIImageView *)[self.view viewWithTag:100]).image = self.mImage;
这是仪器的屏幕,在发出内存警告后第二次崩溃。
我没有看到我在这里使用的“imageCopy”方法有什么大问题。
非常感谢您对此的任何帮助。 谢谢和干杯,
【问题讨论】:
"我有一个图像数组(在这个例子中是一个大小为 2 的数组),我在其中加载了一个图像..." "我使用的图像有点大,大约 7MB... " 显然,这不是明智之举。 【参考方案1】:我发现这是一个循环引用问题。因此,当新内容替换数组中的旧内容时,过去的对象仍然存在。这是一个非常有趣的发现,因为在内存泄漏分析器中它显示的数据泄漏只有几 KB,您不会怀疑这是因为未释放的虚拟内存只有几百兆字节 (MB)。
作为一个非常抽象的例子。
ClassA
@property (strong) ClassB *obj
----------
ClassB
@property (strong) ClassA *obj
- (id)initWithA:(ClassA *)objA;
----------
因此,当您删除 A 时,两个对象都不会被正确释放。在我的情况下,泄漏分析器跟踪的泄漏对于两个对象来说都是几 KB,即使 CoreGraphics 计算挂在虚拟内存中大约 200MB 的数据上。
修复是将 ClassB 中的 A 引用标记为弱。
ClassB
@property (weak) ClassA *obj
- (id)initWithA:(ClassA *)objA;
判决
永远不要低估内存泄漏,无论大小 & arc 或 mrc【讨论】:
【参考方案2】:问题可能是 imageNamed:
方法缓存了加载的图像,显然没有办法在内存警告后以编程方式清除缓存。
除了imageNamed:
,您还可以使用不缓存图像的其他方法,例如initWithData:
。你会发现一个详细的讨论here。
【讨论】:
感谢您的意见。但它仍然是相同的结果。同样来自文档,它指出“此方法在系统缓存中查找具有指定名称的图像对象,如果存在则返回该对象。如果匹配的图像对象不在缓存中,则此方法从指定文件加载图像数据,缓存它,然后返回结果对象。" 我认为问题在于 imageNamed: 缓存了多个图像,并且在不再需要图像时不会自动释放内存。但是如果你用非缓存方法得到了同样的结果,那我们再找一个原因……以上是关于加载 UIImage 时 iOS 应用程序崩溃(虚拟内存未清理)的主要内容,如果未能解决你的问题,请参考以下文章
应用启动时加载用户配置文件,选择视图时崩溃,将 PFFile 转换为 UIImage