异步自动释放池
Posted
技术标签:
【中文标题】异步自动释放池【英文标题】:Async autoreleasepool 【发布时间】:2021-10-28 05:20:13 【问题描述】:我有一种情况,我使用 async/await
在循环中创建了许多 Cocoa 对象,并且内存激增,因为这些对象仅在循环结束时才被释放(而不是每次迭代)。
解决方案是使用autoreleasepool
。但是,我似乎无法让 autoreleasepool
与 async/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)
内存一直飙升到 220MB,这对我来说有点太多了。
通常,您可以将内部循环包装在 autoreleasepool
中,这样可以解决问题,但是当我使用 async
函数尝试它时,会出现以下错误:
Cannot pass function of type '() async -> ()' to parameter expecting synchronous function type
有没有办法解决这个问题?或者是否有另一种方法可以实现在循环内释放 Cocoa 对象的相同目标?
【问题讨论】:
但这不是“泄漏”。内存在循环期间使用,但在循环结束时释放,对吗? @matt 是的,你是对的。我的错。然而,循环内的内存峰值很多 调度队列和 NSThreads 管理它们自己的自动释放池。那么,maybe Task 也一样吗?如果是这样,只需将您的内部异步函数包装到一个任务中。不过,我自己并没有检查这一点。但知道会很有趣! ;) 你应该在 Swift 论坛上发帖。 forums.swift.org我还没有看到任何关于自动释放池和参与者如何交互的讨论。这可能是一个被忽视的细节。值得提出来! 我无法重现该难度。autoreleasepool
在 async
方法中编译并为我工作得很好。
【参考方案1】:
@CouchDeveloper 提到将getImage
包装在Task
中,因为它有自己的autoreleasepool
,而且它似乎可以工作!
只是改变
func getImage() async -> NSImage?
return NSImage(named: "imagename") // Do some work
到
func getImage() async -> NSImage?
await Task
return NSImage(named: "imagename") // Do some work
.value
【讨论】:
以上是关于异步自动释放池的主要内容,如果未能解决你的问题,请参考以下文章