CIImage内存未释放

时间:2018-12-18 18:53:10

标签: swift macos cifilter swift4.2 ciimage

我正在尝试拍摄一系列图像,同时混合X个图像并生成一个新图像。这是我要做的代码:

static func blendImages(blendFrames: Int, blendMode: CIImage.BlendMode, imagePaths: [URL], completion: @escaping (_ progress: Double) -> Void) {
    var currentIndex = 0

    while currentIndex + blendFrames < imagePaths.count {            
        let currentSubset = Array(imagePaths[currentIndex..<(currentIndex + blendFrames)])

        var currentSubsetIndex = 0

        var firstImage: CIImage?

        while currentSubset.count > currentSubsetIndex + 1 {                
            if firstImage == nil { firstImage = CIImage(contentsOf: currentSubset[currentSubsetIndex]) } //First image allocated in memory

            if let secondImage = CIImage(contentsOf: currentSubset[currentSubsetIndex + 1]) {//Second image allocated in memory
                firstImage = firstImage?.blend(with: secondImage, blendMode: blendMode)
            } //Would expect secondImage to be freed from memory at this point, but it does not happen

            currentSubsetIndex += 1
        } 

        if let finalImage = firstImage {
            let bitMapRep = NSBitmapImageRep(ciImage: finalImage)
            let data = bitMapRep.representation(using: .jpeg, properties: [:])

            do {
                try data?.write(to: URL(fileURLWithPath: "Final-" + String(format: "%03d", currentIndex) + ".jpg"))
            } catch let error as NSError {
                print("Failed to write to disk: \(error)")
            }

        }

        firstImage = nil //Would expect firstImage to be freed from memory at this point (or at beginning of next cycle in while-loop), but it does not happen

        currentIndex += 1
    }
}

还有CIImage的blend函数的代码

extension CIImage {

    enum BlendMode: String {
        case Lighten = "CILightenBlendMode"
        case Darken = "CIDarkenBlendMode"
    }

    func blend(with image: CIImage, blendMode: BlendMode) -> CIImage? {
        let filter = CIFilter(name: blendMode.rawValue)!
        filter.setDefaults()

        filter.setValue(self, forKey: "inputImage")
        filter.setValue(image, forKey: "inputBackgroundImage")

        return filter.outputImage
    }
}

如代码注释中所述,我希望在创建它们的作用域末尾释放在firstImage和secondImage中分配的内存。由于它们都在while循环中创建,因此我希望它们在该循环结束时被释放,但是,似乎没有发生。但是这里没有内存泄漏,因为blendImages函数完成后,内存已被适当释放(但是,这太迟了,因为代码可以运行成百上千个图像,从而使该应用消耗了TB的TB)。数据释放之前)。 如果有人能看到我的代码中的缺陷以及如何提高其内存效率,那将不胜感激。

1 个答案:

答案 0 :(得分:1)

您应该使用autoreleasepool函数在其作用域内强制释放对象。此功能将帮助您更精确地管理内存占用。

static func blendImages(blendFrames: Int, blendMode: CIImage.BlendMode, imagePaths: [URL], completion: @escaping (_ progress: Double) -> Void) {
    var currentIndex = 0

    while currentIndex + blendFrames < imagePaths.count {
        autorelease {
            // your code
        }

        currentIndex += 1
    }
}

您可以选中此post以获取更多信息。