我要遍历大量照片,因为它们太大而无法容纳所有照片,因此我必须通过以下方式更新它们:1)从文件中单独加载它们2)执行更新3)保存到文件。这是一个简化的示例(由于某些原因,{@ {1}}部分在Simulator中不起作用):
CIImage
如果我不打import SwiftUI
struct Photo {
let body: Data?
let size = CGSize(width: 1000, height: 1000)
let bytesPerPixel: Int = 4
func load() -> Photo {
let data = Data(count: Int(size.width) * Int(size.height) * bytesPerPixel)
return Photo(body: data)
}
}
struct ContentView: View {
let photos: [Photo] = Array(repeating: Photo(body: nil), count: 100)
var body: some View {
VStack {
Button(action: { self.overloadMemory() }) { Text("Overload Memory") }
}
}
private func overloadMemory() {
for photo in photos {
guard let data = photo.load().body else { continue }
let bytesPerRow = Int(photo.size.width) * photo.bytesPerPixel
let ciImage = CIImage(bitmapData: data,
bytesPerRow: bytesPerRow,
size: photo.size,
format: .BGRA8,
colorSpace: CGColorSpace(name: CGColorSpace.genericRGBLinear)!)
let uiImage = UIImage(ciImage: ciImage)
print("Saving: \(uiImage.size)")
saveFile(image: uiImage) // Leaving this uncommented causes a memory crash. Leaving it commented shows no memory spike in the "Memory Report" panel.
}
}
private func saveFile(image: UIImage) {
let id = UUID()
let fileName = "\(id).png"
let data = image.pngData()!
print("Saving: \(id)")
let appSupportPath = try! FileManager.default.url(for: .applicationSupportDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: true)
let savePath = appSupportPath.appendingPathComponent(fileName)
if FileManager.default.createFile(atPath: savePath.path, contents: data, attributes: .none) {
return
}
print("Failed saving preview")
}
}
,我根本看不到内存使用量激增。如果我致电saveFile
,则会收到“内存不足”错误。根据我对Swift / ARC分配工作原理的理解,是否不应该在循环的每次迭代结束时将每个saveFile
释放出去?当我调用photo
时,为什么直到循环结束之前内存使用量才会累积?