Reputation: 42700
Currently, I have the following code
class ShopViewController: UIViewController {
@IBAction func buy(_ sender: Any) {
Task {
// Will run in main thread, because ShopViewController is
// marked as @MainActor
let success = await Store.INSTANCE.purchase(selectedShop)
}
}
I want the Task
executes in non-main thread, I refactor the code to the following
class ShopViewController: UIViewController {
@IBAction func buy(_ sender: Any) {
Task.detached { [weak self] in
// Will run in non main thread.
guard let self = self else { return }
let success = await Store.INSTANCE.purchase(self.selectedShop)
}
}
Now, the Task
runs in non-main thread.
But, I was wondering, is using Task.detached
a best practice and correct approach, to make sure the Task
is executed in non-main thread?
Upvotes: 2
Views: 1183
Reputation: 437552
There are a few considerations:
Which actor should this Task
use?
Using the main actor with Task { … }
is fine. As soon as it hits the await
keyword, it will suspend execution on the main actor, free it to go do other stuff, and await the results from purchase
. In fact, in practice, you are probably doing something with the success
result (e.g. updating the UI), so you probably want to use Task { … }
to keep it on the current actor.
Which actor should purchase
use?
If Store.INSTANCE.purchase
requires a particular actor, it would define which actor it wants to use, not the caller. It might be an actor
type. It might be decorated with @MainActor
. This is dictated by how Store.INSTANCE
and purchase
are defined. The actor used by buy(_:)
is largely immaterial.
Does it matter which actor purchase
uses?
You say that purchase
is primarily performing network i/o. In that case, it doesn’t matter if it is on the main actor or not. If it was doing something slow and synchronous (e.g., parsing some exceptionally large responses, image processing, etc.), when maybe you would want to explicitly push those tasks off of the current actor, but otherwise it doesn’t matter.
Bottom line, the use of Task.detached
is technically permissible, but generally would not be used in this case.
Upvotes: 2