All what is written below is probably just my misunderstanding, but I will try to explain my experience and I really want to clarify a lot of things for myself.
The process of Incremental Migration to Concurrency Checking is sometimes very difficult because of the huge number of added attributes and many related problems:
- some attributes are introduced, but afterwards replaced by others. This is not a problem when you can get the available information about it
- Sometimes you have to search for information by bits and pieces, looking at posts on this forum, pr`s on github, but there is no single page where you can easily find information
- lack of good examples
- there is no single page with the most known bugs. There aren't many of them, but if you know about them in advance, you don't have to sit for hours and think that you've got something wrong. Radar and issues on github have a lot of them, but it's usually pretty hard to isolate anything from there
Questions to which I cannot find an exhaustive answer:
-
@MainActor(unsafe)
it's the same as@preconcurrency @MainActor
? -
How does
@MainActor(unsafe)
it really work and is its behavior correct in this example:
// -strict-concurrency=targeted or minimal
// -enable-actor-data-race-checks
@MainActor(unsafe)
final 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
_ = viewModel.getValue2()
viewModel.setValue2(3)
}
// -strict-concurrency=complete
// -enable-actor-data-race-checks
@MainActor(unsafe)
final class SomeViewModel {
let value1 = 0
var value2 = 0
func getValue2() -> Int { value2 }
func setValue2(_ newValue: Int) { value2 = newValue }
}
func doSomething2(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
}
-
Is the
@asyncHandler
attribute valid? -
What the
@_unsafeMainActor
,@_unsafeSendable
attributes really do? -
Is
@_unsafeMainActor
an equivalent attribute for a function as opposed to@MainActor(unsafe)
? -
Does the
-warn-concurrency
flag still apply, or does the new flag-strict-concurrency=minimal/targeted/complete
completely replace it? -
Is it true that at this point there is no way to do it without warning and no extra hop with Task:
@MainActor(unsafe)
func foo() {}
RunLoop.main.perform {
foo() // Call to main actor-isolated global function 'foo()' in a synchronous nonisolated context; this is an error in Swift 6
}
Unless you use assumeOnMainActorExecutor
, but this is only available in swift 5.9
for now.