【问题标题】:Memory Leak on scaling image in iOS using SWIFT使用 SWIFT 在 iOS 中缩放图像时出现内存泄漏
【发布时间】:2016-04-25 14:49:32
【问题描述】:

我有一个应用程序可以显示图像并将它们缩放到特定大小。 这是缩放的代码:

static func scaledImage(originalImage image: UIImage, scaledToSize size: CGSize) -> UIImage {        
    UIGraphicsBeginImageContextWithOptions(size, true, 0.0)
    image.drawInRect(CGRectMake(0, 0, size.width, size.height))
    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return scaledImage
}

这是对函数的调用方式:

for i in 0 ..< images.count{
    if let data = images[i].imageData, let originalImage = UIImage(data: data) {
        previewImage = scaledImage(originalImage: originalImage, scaledToSize: desiredSize)            
    } 
} 

应用因 50 张图片而崩溃 当我使用仪器查找内存的分配位置时,它告诉我这一行分配了 960 MB: image.drawInRect(CGRectMake(0, 0, size.width, size.height))

那是相当多的内存。

所以我的问题是这里做错了什么? 如何解决内存泄漏。

我搜索了很多关于如何缩放图像的示例,但它们或多或少是相同的。没有关于内存管理的示例,由于我在图像处理方面没有很多经验,我不知道如何解决这个问题。

这里的任何帮助将不胜感激。 在此先感谢

【问题讨论】:

  • 这不一定是泄漏。图像占用了相当多的内存,如果您同时在内存中保存 50 个(以及 50 个调整大小的版本),您可能会度过一段糟糕的时光。内存中图像的内存大小一般为宽*高*4字节。原始图像及其调整大小的版本是什么尺寸?每种尺寸乘以上述乘以 50。
  • 感谢您的回复。原始图像为全高清。有没有办法优化解决方案,使其更好地工作。还有如何释放图形上下文分配的内存?
  • 1080p 帧每个大小为 8.3 MB。其中 50 个将占用 415 MB 的内存(即使是 50 MB 的内存分配也会导致您在旧 iOS 设备上的应用程序崩溃)。不要一次将所有 50 张图像加载到内存中。按需加载和调整每个图像的大小,最多维护几个图像的缓存。处理完图像后,请确保您没有保留对它的引用。
  • 你必须自动释放对 scaledImage 的调用。
  • 自动释放投票完成了这项工作。 @Darko 谢谢。您可以添加您的评论作为答案,以便我接受它

标签: ios swift image-processing memory-management memory-leaks


【解决方案1】:

您必须自动释放对 scaledImage 的调用。

autoreleasepool {
  previewImage = scaledImage(originalImage: originalImage, scaledToSize: desiredSize)
}

【讨论】:

  • 自动释放池对我不起作用。我每次打电话都会损失 40MB 左右
  • 更新:自动释放池只有在我用它包裹整个循环时才有效。每次我在循环内缩放并耗尽内存时,我只损失了 40MB 左右。
【解决方案2】:

如果您执行数百或数千次操作,您会看到“UIGraphicsGetImageFromCurrentImageContext”将保留内存中的图像,直到代码将控制权返回给运行循环,这可能很长时间不会发生。当 iOS 确定您的应用使用过多内存时,这可能会导致崩溃。

这是自动释放池代码的实现:

func scaledImage(originalImage image: UIImage, scaledToSize size: CGSize) -> UIImage {
    return autoreleasepool { () -> UIImage in
        UIGraphicsBeginImageContextWithOptions(size, true, 0.0)
        image.drawInRect(CGRectMake(0, 0, size.width, size.height))
        let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return scaledImage
    }
}

【讨论】:

    猜你喜欢
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 2013-11-02
    相关资源
    最近更新 更多