I’m not sure how is this being triggered, but sometimes when I call a function inside Task { }
XCode gives an error that instructs me to add await
in the called function.
Here’s a simplified instance I experienced:
public class Loader: UIView {
public class func show(animated: Bool = true) {
// showing the loader code
}
}
enum Utilities {
func doSomeAsyncTask(action: @escaping ()async->()) {
Task {
Loader.show() // XCode error: "Expression is 'async' but is not marked with 'await'"
action()
}
}
}
XCode shows the function is an async one
Does this have something to do that this is a class or something?
>Solution :
UIView
is marked with the global actor @MainActor
. Since Loader
inherits from UIView
, Loader
is implicitly marked with @MainActor
too.
This means that all the methods in Loader
are isolated to the MainActor
. The things in Task { ... }
are not isolated to the MainActor
. Therefore, to run a MainActor
-isolated method in Task { ... }
, you need to await
for it. MainActor
could be busy with something else at that time, and you’d need to wait for a bit before it runs show
.
The methods that do not become async
when you put them in Task { ... }
are probably not isolated to a particular actor, e.g.
// not actor-isolated
func square(_ x: Int) -> Int { x * x }
enum Utilities {
func doSomeAsyncTask(action: @escaping ()async->()) {
Task {
print(square(4)) // doesn't need async
await action()
}
}
}