The Sendable protocol is a crucial feature in Swift's concurrency model. It helps ensure data safety when working with actors and concurrent tasks.
Introduced in Swift 5.5, the Sendable protocol marks types that can be safely shared across concurrent contexts. It's a key component in preventing data races and maintaining thread safety.
Many Swift standard library types automatically conform to Sendable. For custom types, you can explicitly conform to the protocol:
struct MyStruct: Sendable {
let immutableProperty: Int
// All stored properties must be Sendable
}
class MyClass: Sendable {
let immutableProperty: String
// Classes must be marked as 'final' to conform to Sendable
}
To conform to Sendable, types must meet certain criteria:
Sendable is particularly important when working with Swift Actors. It ensures that data passed between actors is safe for concurrent access:
actor DataManager {
func process(data: some Sendable) {
// Safe to use 'data' here
}
}
let manager = DataManager()
let safeData = SafeData() // Conforms to Sendable
await manager.process(data: safeData) // Compiles successfully
Closures can be marked as @Sendable to indicate they're safe for concurrent execution:
let sendableClosure: @Sendable () -> Void = {
print("This closure is safe for concurrent contexts")
}
Task {
await someActor.performWork(sendableClosure)
}
The Sendable protocol is a powerful tool in Swift's concurrency toolkit. By leveraging Sendable, developers can write safer, more robust concurrent code. It works hand-in-hand with other concurrency features like async/await and actors to create efficient, thread-safe applications.