Swift5 MacOS ImageResize 内存问题 [英] Swift5 MacOS ImageResize memory issue

查看:16
本文介绍了Swift5 MacOS ImageResize 内存问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是使用 Swift 进行 Mac OS 应用程序开发的新手.但我尝试制作简单的 ImageResizer 应用程序.我必须调整 50k 图像的大小.10 小时后,内存增加到接近 120GB.我以为 Swift 也有垃圾收集器.为什么会增加内存?我会告诉你我的代码.

I am new to Mac OS App Development with Swift. But I tried to make the simple ImageResizer app. I have to resize 50k images. After 10 hours, the memory has increased to nealy 120GB. I thought Swift also has Garbage collector. Why does it increase memory? I will show you my code.

for i in 0..<paths.count {
    let path = paths[i]

    if let image = NSImage(contentsOf: path) {
        ...

        if self.resize(image: image, size: size, to: URL(fileURLWithPath: resizedImagePath)) {
            print("Image saved to (resizedImagePath)")
            continue
        }
    }
}

func resize(image: NSImage, size: Int, to url: URL) -> Bool {
    if !image.isValid {
        print("invalid image")
        return false
    }

    guard let pixelsWide = image.representations.first?.pixelsWide else {
        return false
    }

    let factor: CGFloat = CGFloat(pixelsWide) / image.size.width

    var width: CGFloat = CGFloat(size)
    var height: CGFloat = CGFloat(size)
    if image.size.width > image.size.height {
        height = width * image.size.height / image.size.width
    } else {
        width = height * image.size.width / image.size.height
    }

    let rep = NSBitmapImageRep(bitmapDataPlanes: nil,
                               pixelsWide: Int(width),
                               pixelsHigh: Int(height),
                               bitsPerSample: 8,
                               samplesPerPixel: 4,
                               hasAlpha: true,
                               isPlanar: false,
                               colorSpaceName: .deviceRGB,
                               bytesPerRow: Int(width * 4),
                               bitsPerPixel: 32)
    rep?.size = NSSize(width: width / factor, height: height / factor)

    let ctx = NSGraphicsContext(bitmapImageRep: rep!)
    NSGraphicsContext.saveGraphicsState()
    NSGraphicsContext.current = ctx
    image.draw(in: NSMakeRect(0, 0, width / factor, height / factor))
    ctx?.flushGraphics()
    NSGraphicsContext.restoreGraphicsState()

    // Get NSData, and save it
    let data = rep?.representation(using: .png, properties: [:]) // properties as! [String : Any]) //
    do {
        try data?.write(to: url)
        return true
    }
    catch {
        return false
    }
}

推荐答案

你可以把你的整个代码放在你的循环中 autoreleasepool:

You can put your whole code that it is inside your loop inside an autoreleasepool:

如果你编写了一个创建许多临时对象的循环.您可以使用循环内的自动释放池块来处理这些对象在下一次迭代之前.在循环中使用自动释放池块有助于减少应用程序的最大内存占用.

If you write a loop that creates many temporary objects. You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application.

for i in paths.indices {
    autoreleasepool {
        // all your image resizing code goes here
    }
}

这篇关于Swift5 MacOS ImageResize 内存问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆