【问题标题】:Release memory after UIGraphicsImageRenderer workUIGraphicsImageRenderer 工作后释放内存
【发布时间】:2021-08-05 17:06:59
【问题描述】:

我有许多图像保存在 Assets.xcassets 中。我正在调整它们的大小,使它们变小。然后以后我不再需要这些图像了。图片没有显示,只是准备好了。因此,获取图像、调整大小并保留的类现在已成功取消初始化
但是 UIGraphicsImageRenderer 调整图像大小后的内存没有释放。内存使用率保持在同一水平。即使我根本没有像下面的示例代码那样使用图像。 我觉得有些不对劲。实际上,我调整了图像的大小以使用更少的内存,但相反 - 调整大小的图像使用了更多的内存,并且在类所有者被取消后它不会释放。

如何释放内存?

Apple 的文档说:“...图像渲染器保留 Core Graphics 上下文的缓存,因此重用相同的渲染器可能比创建新渲染器更有效。” - 但我不需要它!如何关闭它? 有 28 张图像,这似乎没什么大不了的。但是我有大约 100-300 张图像应该调整大小、裁剪和使用 UIGraphicsImageRenderer 进行其他操作,最终使用大约 800-900 Mb 的内存来缓存一些已经完成的渲染工作。

你可以拿下面的代码试试。

class ExampleClass {
    
    func start() {
        Worker().doWork()
    }
}

class Worker {
    
    deinit {
        print("deinit \(Self.self)")
    }
    
    func doWork() {
        
        var urls: [String] = []
        _ = (1...28).map({ urls.append("pathToTheImages/\($0)") })
        // images with resolution 1024.0 x 1366.0 pixels
        
        for url in urls {
            let img = UIImage(named: url)!  // Memory usage: 11.7 MB
            //let cropped = resizedImage(original: img, to: UIScreen.main.bounds.size)
            //With this line above - Memory usage: 17.5 MB even after this class has been deinited
        }
    }
    
    // from 2048 × 3285 pixels >>> to >>> 768.0 x 1024.0 pixels  --- for iPad Pro (9.7-inch)
    func resizedImage(original: UIImage, to size: CGSize) -> UIImage {
        let result = autoreleasepool { () -> UIImage in
            let renderer = UIGraphicsImageRenderer(size: size)
            let result = renderer.image { (context) in
                original.draw(in: CGRect(origin: .zero, size: size))
            }
            return result
        }
        return UIImage(cgImage: result.cgImage!, scale: original.scale, orientation: original.imageOrientation)
    }
}

【问题讨论】:

  • 我好像前几天看到了一个很相似的话题。
  • 您是在抱怨图像渲染器图形上下文没有被释放,还是图像没有被释放?有问题的内存是什么?使用仪器找出答案。
  • @matt,我问的是渲染器图形上下文,而不是图像。所有 UIImage 对象都已被取消初始化。
  • 它们可能已被取消初始化,但它们也被缓存。在我看来,你只是在猜测。别。使用仪器。
  • @matt,好的。我在 Instruments (Allocations) 中看到 - 分配了 28 个 CGImage。我知道他们缓存了。这就是问题所在,也是我最初的问题。如何释放内存并处理比原始图像占用更多内存的缓存图像?

标签: ios swift memory-management uiimage core-graphics


【解决方案1】:

资产目录不适用于您放置它们的用途。资产目录中图像的目的是直接显示它。如果您有很多图像要加载、调整大小并保存在其他地方而不显示,您需要将它们保存在顶层的应用程序包中,以便您可以调用不缓存图像的init(contentsOfFile:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多