问题描述
我有一组图像,需要将这些图像与不同的混合选项合并。我发现,在此过程中,不会在每个周期的步骤中释放内存。即使没有引用创建的图像。在此过程中,我的应用程序崩溃了,因为我要合并很多图像。有什么解决方法或技巧,如何在不增加内存的情况下做到这一点? 可以使用以下代码进行复制:
import UIKit
import CoreImage
class ViewController: UIViewController {
var images =
[
UIImage.init(color: UIColor.green,size: CGSize(width: 2048,height: 1152))!,UIImage.init(color: UIColor.green,]
override func viewDidLoad() {
super.viewDidLoad()
var result = UIImage.init(color: UIColor.blue,height: 1152))!
for image in images {
//each step reference to prevIoUs result released,but memory is growing
result = merge(result,image)
sleep(1)
}
}
public func merge(_ back: UIImage,_ top: UIImage) -> UIImage {
var size = CGSize(width: 2048,height: 1152)
UIGraphicsBeginImageContextWithOptions(size,false,UIScreen.main.scale)
let rec = CGRect(x: 0,y: 0,width: 2048,height: 1152)
back.draw(in: rec)
//multiply is just for example,it can be different blending option
top.draw(in: rec,blendMode: .multiply,alpha: 1)
var newImage: UIImage = UIGraphicsGetimageFromCurrentimageContext()!
UIGraphicsEndImageContext()
return newImage
}
}
extension UIImage {
public convenience init?(color: UIColor,size: CGSize) {
let rect = CGRect(origin: .zero,size: size)
UIGraphicsBeginImageContextWithOptions(rect.size,true,0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetimageFromCurrentimageContext()
UIGraphicsEndImageContext()
guard let cgImage = image?.cgImage else {
return nil
}
self.init(cgImage: cgImage,scale: UIScreen.main.scale,orientation: Orientation.up)
}
}
带有虚拟图像的阵列和循环。我添加了睡眠,以便在Instruments
中看到更好的效果(不睡眠会得到相同的结果)
如您所见,每秒的存储量正在增加。 有什么办法可以在每个步骤中将内存保持在同一级别? 非常感谢!
解决方法
您可以将合并包装到autoreleasepool
范围内:
for image in images {
autoreleasepool {
result = merge(result,image)
}
sleep(1)
}
UIKit
将其生成的对象添加到autoreleasepool
中,以便在运行循环周期结束时将其释放。