给出以下任务:
我写了这个小小的命令行程序:
import ArgumentParser
import AppKit
import Foundation
struct CheckImages: ParsableCommand {
@Option(help: "The images root directory")
var path: String
func run() throws {
let directories = try FileManager.default.contentsOfDirectory(atPath: path)
for directory in directories {
if directory == ".DS_Store" {
continue
}
let prefix = self.path + "\(directory)/PREFIX_\(directory)"
let imageName = prefix + ".jpg"
let image = NSImage(contentsOfFile: imageName)
if image == nil {
print("PROBLEM \(imageName)")
}
}
}
}
CheckImages.main()
每个图像的大小约为20MB。我总共要检查约150.000张图像。
[不幸的是,XCode以Program ended with exit code: 9
终止程序。深入研究(使用Instruments)可以发现,这个小小的帮助应用程序消耗了NSImage.init()
中的所有内存。由于NSImage
是成熟的对象,因此我怀疑它是否存在任何问题。因此,我的问题是,有人可以向我解释这种行为吗?
我的环境:
NSImage
只是ObjC-NSImage对象的包装,所以它需要一个自动释放池来管理释放。我们现在是2020年,我们必须以这种方式来管理这类事情吗?在这篇文章中,我找到了上述问题的答案:Is it necessary to use autoreleasepool in a Swift program?
可以在这里找到另一篇不错的文章:https://swiftrocks.com/autoreleasepool-in-2019-swift.html
因此,上面的代码必须看起来像这样:
import ArgumentParser
import AppKit
import Foundation
struct CheckImages: ParsableCommand {
@Option(help: "The images root directory")
var path: String
func run() throws {
let directories = try FileManager.default.contentsOfDirectory(atPath: path)
for directory in directories {
if directory == ".DS_Store" {
continue
}
autoreleasepool {
let prefix = self.path + "\(directory)/PREFIX_\(directory)"
let imageName = prefix + ".jpg"
let image = NSImage(contentsOfFile: imageName)
if image == nil {
print("PROBLEM \(imageName)")
}
}
}
}
}
CheckImages.main()