class NonSendableClass {
var data: String
init(data: String) {
self.data = data
}
}
@available(*, unavailable)
extension NonSendableClass: Sendable { }
actor SomeActor1{
func foo(_ object: NonSendableClass) async -> Void {
object.data = "world"
}
func bar(_ closure: @escaping () async -> Void) async -> Void {
await closure()
}
}
let actor1 = SomeActor1()
actor SomeActor2{
func test1() async {
let nonSendableObj = NonSendableClass(data: "hello")
// Passing argument of non-sendable type 'NonSendableClass' into actor-isolated context may introduce data races; this is an error in the Swift 6 language mode
await actor1.foo(nonSendableObj)
}
func test2() async {
let nonSendableObj = NonSendableClass(data: "hello")
let nonSendableClosure = {() async -> Void in
try? await Task.sleep(nanoseconds: UInt64.random(in: 0..<10))
nonSendableObj.data = "world"
}
// This doesn't trigger any warning
await actor1.bar(nonSendableClosure)
}
}
Sending a non-sendable object from a method on Actor2 to Actor1 triggers a warning complaining NondSendableClass type is not sendable, but sending a non-sendable closure from a method on Actor2 to Actor1 is fine?
I'm pretty sure nonSendableFunc
is not sendable because if I add @Sendable
in SomeActor1.bar(), it triggers a warning Converting non-sendable function value to '@Sendable () async -> Void' may introduce data races
Why does sending a non-sendable object behave different than sending a non-sendable closure? I find it a bit hard to understand...