But I think COW is thread safe, right? I wrote an equivalent version using Swift concurrency and it compiles (note the var b = a line). I wonder what's the underlying difference between DispatchQueue version and my version? Does this example indicate Swift concurrency is more powerful?
@concurrent
func perform(_ fn: sending () -> Void) async {
fn()
}
@MainActor
func test() async {
var a = [1, 2, 3]
var b = a
for i in 0..<a.count {
await perform {
a[i] = 0
}
}
}
The sending parameter is a workaround required even when there is no COW involved. See A limitation in RBI caused by closure isolation inference?.
An alternative version without `sending`
This compiles too.
@globalActor actor MyGlobalActor {
static let shared = MyGlobalActor()
}
@MyGlobalActor
func test() async {
var a = [1, 2, 3]
var b = a
for i in 0..<a.count {
await perform { @MainActor in
a[i] = 0
}
}
}
@MainActor
func perform(_ fn: @MainActor () -> Void) async {
fn()
}