iOS - 调整图像大小导致内存泄漏

Posted

技术标签:

【中文标题】iOS - 调整图像大小导致内存泄漏【英文标题】:iOS - Resizing an image is causing a memory leak 【发布时间】:2014-03-30 08:36:45 【问题描述】:

我正在尝试使用以下代码在 for 循环中调整多个 UIImage 对象的大小:

CGFloat scaledToWidth:resized_width = 160.0;
for(UIImage *img in imageArray) 
    UIImage *resizedImageSecond = [self resizeImage:img scaledToWidth:resized_width]; 
    //Do something with resizedImageSecond      


-(UIImage*)resizeImage:(UIImage*) sourceImage scaledToWidth: (float) i_width

    float oldWidth = sourceImage.size.width;
    float scaleFactor = i_width / oldWidth;

    float newHeight = sourceImage.size.height * scaleFactor;
    float newWidth = oldWidth * scaleFactor;

    UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
    [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();
    return newImage;

但我发现我的内存使用量在resizeImage:scaledToWidth: 的每次迭代中都会迅速增加。我在这里没有看到任何明显的内存泄漏,但我也不确定。

有没有人知道为什么我的内存使用量会在这个函数中增加?我在这里不知所措。不幸的是,我在imageArray 里面有大约 100 个UIImage,所以我需要尽可能地保守记忆。

【问题讨论】:

如果您要在创建后释放调整大小的图像,则将循环主体包裹在 @autoreleasepool 块中。如果没有,那么您需要找到一种比直接循环占用更少资源的方法。 @CodaFi 我的项目是 ARC,所以我没有明确地在任何地方发布它。我应该吗? 另外,使用 Instruments 并学习部署 Allocations Leaks 工具并通过调用者递增和递减引用计数的列表查看泄漏。它是一个非常宝贵的学习工具,也是一个调试工具。 ARC 与否,@autoreleasepool 指令可供使用。如果您对它们的用法感到困惑,请看这里:developer.apple.com/library/ios/documentation/Cocoa/Conceptual/… @RobP 我试过仪器。我的印象是,拿起CoreFoundation 对象并非易事,这就是支持UIImage 的原因。如果我错了,我会更深入地调查。 【参考方案1】:

您在每次使用 resizeImage:scaledToWidth: 时创建新的 UIImage 实例。这就是内存增加的原因。最简单的解决方案是在不再需要图像时将图像设置为nil

for(UIImage *img in imageArray) 
    @autoreleasepool 
        UIImage *resizedImage = [self resizeImage:img scaledToWidth:resized_width]; 

        //Do something with resizedImage 

        resizedImage = nil;
         

【讨论】:

那么,为什么在一个 ARC 项目(比如我的项目)中,它超出范围时不会发布? (即继续循环?) 我其实已经设置了resizedImage = nil,并没有变化。 ARC 不保证对象的生命周期。你所知道的是,当地人会在某个时候被释放。这可能完全无法解决问题。 @IgorMatyushkin 仍然没有运气。内存仍然随着循环的每次迭代而增加。并且在循环和方法退出后内存仍然保留。我的代码和我上面的完全一样。如果我不打电话给resizeImage,它可以正常工作。这让我相信resizeImage 有问题。因此,我的 OP 中的 cmets。有什么想法吗? 您是否可能正在做一些事情来保留这批新图像?也许将它们放在数据结构中,或者使用不同的对象对它们进行强引用?

以上是关于iOS - 调整图像大小导致内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

ios在画布上使用display:none绘制图像导致内存泄漏

为啥这会导致内存泄漏?

iOS4 调用 ImageNamed:仍然泄漏或导致内存问题?

Awesomium.NET 在调整大小时崩溃 - 内存泄漏

iOS 内存泄漏导致更改视图控制器崩溃

记一次内存溢出查找分析文档