We can create a @MainActor
Task
like this:
Task { @MainActor in
print("hi")
}
But also with @MainActor(unsafe)
like this:
Task { @MainActor(unsafe) in
print("hi")
}
What's the difference between these two methods?
We can create a @MainActor
Task
like this:
Task { @MainActor in
print("hi")
}
But also with @MainActor(unsafe)
like this:
Task { @MainActor(unsafe) in
print("hi")
}
What's the difference between these two methods?
The main purpose of @MainActor(unsafe)
is to make incremental adoption of concurrency easier. You can read this in detail explained in the proposal. If you mark your type as @MainActor(unsafe)
if you try to access properties and methods synchronously in code that hasn't adopted async/await
without breaking anything.
For example following code won't compile with only @MainActor
as here actor isolated property accessed from synchronous context:
@MainActor
class SomeViewModel {
let value1 = 0
var value2 = 0
func getValue2() -> Int { value2 }
func setValue2(_ newValue: Int) { value2 = newValue }
}
func doSomething(with viewModel: SomeViewModel) {
_ = viewModel.value1
_ = viewModel.value2 // ERROR: Property 'value2' isolated to global actor 'MainActor' can not be referenced from this synchronous context
_ = viewModel.getValue2() // ERROR: Call to main actor-isolated instance method 'getValue2()' in a synchronous nonisolated context
viewModel.setValue2(3) // ERROR: Call to main actor-isolated instance method 'setValue2' in a synchronous nonisolated context
}
But if you change @MainActor
to @MainActor(unsafe)
there are no more build errors. Note that @MainActor(unsafe)
is only applicable to swift 5 code to make incremental adoption of concurrency easier and in swift 6 it won't have any effect and would behave the same as @MainActor
.
Also @MainActor(unsafe)
is interchangeable with @preconcurrency @MainActor
. You also can use -warn-concurrency
compiler option to get all the errors that you would get with only @MainActor
as warnings.
© 2022 - 2025 — McMap. All rights reserved.