Swift-NSImage,内存泄漏



给出以下任务:

  • 扫描文件夹,其中包含包含图像的子文件夹,并确保没有图像损坏
  • 使用MacOS和Swift
  • 打开每个图像并检查其是否已损坏

我写了这个小小的命令行程序:

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。我总共有大约150000张图片要检查。

不幸的是,XCode终止了带有Program ended with exit code: 9的程序。深入研究(使用Instruments(发现,这个小小的帮助应用程序消耗了我在NSImage.init()中的所有内存。由于NSImage是一个成熟的物体,我怀疑它是否有任何问题。因此,我的问题是,有人能向我解释这种行为吗?

我的环境:

  • XCode 11.4.1版(11E503a(
  • Apple Swift 5.2.2版(swiftlang-11003.0.32.6 clang-1103.0.32.51(

在回答我自己的问题时,我需要一个自动释放池。由于我从来没有用Objective-C编程,所以我不知道自动释放池之类的东西。由于NSImage"只是"ObjC NSImage对象的包装器,因此它需要一个自动释放池来管理释放。我们在2020年,我们必须以这种方式管理这样的事情?

在这篇文章中,我找到了上述问题的答案:是否有必要在Swift程序中使用自动释放池?

另一个不错的帖子可以在这里找到: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()

最新更新