I have a situation where I'm creating many Cocoa objects in a loop using async/await, and the memory spikes because the objects are only released when the loop is over (instead of every iteration).
The solution would be to use an autoreleasepool. However, I can't seem to get autoreleasepool to work with async/await.
Here is an example:
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)
}
}
The memory spikes all the way up to 220MB, which is a bit too much for me.
Normally, you could wrap the inner loop in a autoreleasepool, and it would fix the problem, but when I try it with an async function, I get this error:
Cannot pass function of type '() async -> ()' to parameter expecting synchronous function type
Is there any way around this? Or is there another method to accomplish the same goal of releasing the Cocoa objects inside of the loop?
@CouchDeveloper mentioned to wrap getImage in a Task, as it has its own autoreleasepool, and it seems to work!
Just change
func getImage() async -> NSImage? {
return NSImage(named: "imagename") // Do some work
}
to
func getImage() async -> NSImage? {
await Task {
return NSImage(named: "imagename") // Do some work
}.value
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With