异步自动释放池

rec*_*cha 5 macos cocoa async-await swift swift-concurrency

我有一种情况,我正在循环中创建许多 Cocoa 对象async/await,并且内存峰值,因为这些对象仅在循环结束时释放(而不是每次迭代)。

解决方案是使用autoreleasepool. 但是,我似乎无法autoreleasepoolasync/await

这是一个例子:

func getImage() async -> NSImage? {
    return NSImage(named: "imagename") // Do some work
}

Task {
    // This leaks
    for _ in 0 ..< 1000000 {
        let image = await getImage()
        print(image!.backgroundColor)
    }
}
Run Code Online (Sandbox Code Playgroud)

内存一路飙升至 220MB,这对我来说有点太多了。

通常,您可以将内部循环包装在 a 中autoreleasepool,它可以解决问题,但是当我使用函数尝试它时async,我收到此错误:

Cannot pass function of type '() async -> ()' to parameter expecting synchronous function type
Run Code Online (Sandbox Code Playgroud)

有没有办法解决?或者是否有另一种方法可以实现在循环内释放 Cocoa 对象的相同目标?

rec*_*cha 8

@CouchDeveloper 提到要包装getImage在 a 中Task,因为它有自己的autoreleasepool,而且它似乎有效!

只是改变

func getImage() async -> NSImage? {
    return NSImage(named: "imagename") // Do some work
}
Run Code Online (Sandbox Code Playgroud)

func getImage() async -> NSImage? {
    await Task {
        return NSImage(named: "imagename") // Do some work
    }.value
}
Run Code Online (Sandbox Code Playgroud)