Wesley de Groot's Blog
Understanding Sendable in Swift

Back

With the introduction of Swift 5.5, Apple brought significant enhancements to concurrency, including the Sendable protocol and the @Sendable attribute. These additions are crucial for ensuring thread safety in concurrent programming.
Let's dive into what Sendable is, why it's important, and how you can use it in your Swift projects.

What is Sendable?

The Sendable protocol in Swift indicates that a type is safe to be used concurrently.
This means that instances of a Sendable type can be safely passed between different threads without causing data races or other concurrency issues.

Why is Sendable Important?

Concurrency introduces the challenge of ensuring that data accessed by multiple threads remains consistent and free from race conditions.
The Sendable protocol helps the Swift compiler enforce these safety guarantees.
By marking types as Sendable, you tell the compiler that these types can be safely shared across different threads.

Using @Sendable

The @Sendable attribute can be applied to closures and functions to indicate that they are safe to be executed concurrently.
When you mark a closure or function with @Sendable, the compiler enforces certain rules to ensure thread safety.
For example, any values captured by a @Sendable closure must themselves be Sendable.

Here's a simple example:

import Foundation

let task = Task { @Sendable in
    // This closure is marked as @Sendable
    print("Running a sendable task")
}

In this example, the closure passed to Task is marked with @Sendable, ensuring that any captured values are safe for concurrent use.

Conforming to Sendable

To make a custom type conform to Sendable, you need to ensure that all its stored properties are also Sendable.
Here's an example of a struct conforming to Sendable:

struct MyData: Sendable {
    let value: Int
}

let data = MyData(value: 42)

In this case, MyData is a simple struct with a single Int property, which is inherently Sendable.

Sendable in closures

When you use a closure that captures values, you need to ensure that those values are Sendable.

Here's an example:

import Foundation

let value = 42

let closure: @Sendable () -> Int = {
    return value
}

let result = closure()

print(result) // Output: 42

Practical Applications

Using Sendable and @Sendable is particularly useful in scenarios involving actors and tasks.
For instance, when you pass data between different actors or tasks, ensuring that the data is Sendable helps maintain thread safety and prevents potential concurrency issues.

Conclusion

The introduction of the Sendable protocol and the @Sendable attribute in Swift marks a significant step forward in making concurrent programming safer and more reliable. By understanding and utilizing these features, you can write more robust and thread-safe Swift code.

References:

Read more

Share


Share Mastodon Twitter LinkedIn Facebook
x-twitter mastodon github linkedin discord threads instagram whatsapp bluesky square-rss sitemap