After Swift 5.5 Apple introduced the Sendable and @Sendable in Swift.
Sendable and @Sendable in Swift address the problem of type-checking values passed between concurrency constructs and actor messages.
Let’s dive into the article.
Sendable Protocol
We can pass the Sendable values from one concurrency domain to another.
For instance, you can pass a sendable value as the argument when calling an actor’s methods. Below can be marked as Sendable:
- Value types
- Reference types with no mutable storage
- Reference types that internally manage access to their state
- Functions and closures (by marking them with
@Sendable
)
Here is an example of how integers support the Sendable protocol:
1 |
extension Int: Sendable {} |
Creating a struct with a single value of type Int automatically conforms to Sendable.
1 2 3 |
struct Abc { var xyz: Int } |
If the generic type does not conform to Sendable, the compiler does not add implicit conformance.
Here is how we create a struct with conformance to Sendable.
1 2 3 |
struct Box<Val: Sendable> { var abc: Val } |
Here is an example of enumeration.
The Sendable protocol and closure indicate whether the public API of the passed values passed thread-safe to the compiler. However, it also reduces the chances of the race around conditions.
Using Sendable and @Sendable in Swift
Above all, there are cases in which the compiler does not add implicit conformance, we need to conform to the protocol manually.
For instance, the class that is immutable can conform to the Sendable protocol
1 2 3 4 5 6 |
final class Abc: Sendable { let x: String init(x: String) { self.x = x } } |
In addition, the classes which are mutable need to be marked as @unchecked attribute to indicate our class is actually thread-safe due to internal locking mechanisms.
Above all, the Non-final class cannot conform to Sendable, we have to use @unchecked Sendable.
1 2 3 4 5 |
class Abc: @unchecked Sendable { let x: String init(x: String) { self.x = x } } |
In conclusion, we can use @Sendable to tell the compiler that no extra synchronization is needed as all captured values in the closure are thread-safe.
For more details please visit here.
To read more articles please visit here.