I wanted to make a simple function that uploads only those images that follow a certain order. I tried using Task Groups for this as that way I can return back to the suspension point after all child Tasks have completed. However, I ran into an error I don't understand.
class GameScene: SKScene {
var images = ["cat1", "mouse2", "dog3"]
func uploadCheckedImages() async {
await withTaskGroup(of: Void.self) { group in
for i in images.indices {
let prev = i == 0 ? nil : images[i - 1] // << Error: Actor-isolated property 'images' cannot be passed 'inout' to 'async' function call
let curr = images[i] // << Error: Actor-isolated property 'images' cannot be passed 'inout' to 'async' function call
if orderIsPreserved(prev ?? "", curr) {
group.addTask { await self.uploadImage(of: curr) }
}
}
}
}
func orderIsPreserved(_ a: String, _ b: String) -> Bool {
return true
}
func uploadImage(of: String) async {
try! await Task.sleep(for: .seconds(1))
}
}
I have a handful of questions related to this error.
Why does a SKScene subclass raise this error? When I don't subclass SKScene this error disappears. What's so special about SKScene that raises this error?
Where is the Actor and why only Task Groups? Isn't this a class? I thought it may have to do something with "Oh a task has to guarantee so and so things" but when I switch
withTaskGroup(of:_:)
to a regularTask { }
, this error again disappears. So I'm not sure why this is only happening with Task Groups.Can I ease the compilers worries about it being passed as inout? Since I know that this function isn't altering the value of
images
, is there any way I can ease the compilers worries about "don't pass actor-isolated properties as inout" (sort of like using thenonmutating
keyword for structs)?