Swift Sendable
The Sendable protocol marks a type whose values can cross between separate tasks safely. The @Sendable mark states the same promise for a closure value.
A Sendable struct in a detached task
The Point struct declares Sendable conformance and holds two Int values. A detached task reads the point and returns the sum of its parts.
struct Point: Sendable {
var x: Int
var y: Int
}
let point = Point(x: 3, y: 4)
let task = Task.detached {
point.x + point.y
}
let result = await task.value
print(result)A closure marked @Sendable
The run function accepts work as an @Sendable closure, and the @escaping mark lets that closure outlive the call. The function starts the work in a detached task, and the awaited result prints 20.
func run(work: @escaping @Sendable () -> Int) async -> Int {
let task = Task.detached {
work()
}
return await task.value
}
let result = await run {
15 + 5
}
print(result)Two detached tasks in a fixed print order
Two Reading values cross into two detached tasks. The program awaits the first task and then the second task, so the printed lines keep their written order.
struct Reading: Sendable {
var label: String
var value: Int
}
let first = Reading(label: "First", value: 10)
let second = Reading(label: "Second", value: 20)
let firstTask = Task.detached {
first.value + 1
}
let secondTask = Task.detached {
second.value + 1
}
let firstResult = await firstTask.value
let secondResult = await secondTask.value
print(firstResult)
print(secondResult)Example
struct Message: Sendable {
var text: String
var count: Int
}
let message = Message(text: "Ready", count: 3)
let task = Task.detached {
message.text
}
let text = await task.value
print(text)
print(message.count)Key points
- A struct can declare Sendable conformance in its definition line.
- A struct fits Sendable when each stored property holds a Sendable value.
- A Sendable value can be handed to a detached task.
- A closure type marked @Sendable can travel in the same way.
- A detached task hands its result back through await on its value.
- Printing results after separate awaits keeps the printed order fixed.
In this example, a Message value crosses into a detached task. The task returns the stored text, and the awaited result prints Ready. The count read afterwards prints 3.
Note
Int and String values already conform to Sendable.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does Sendable conformance promise about a value?