What is Swift's concurrency model — Sendable and actor isolation?
Answer
Swift's strict concurrency model (fully enabled in Swift 6) prevents data races at compile time through Sendable and actor isolation. Sendable protocol: a type is Sendable if it's safe to share across concurrency domains (actors, tasks). Value types (struct, enum with Sendable properties) are implicitly Sendable. Classes must be explicitly marked: // Implicitly Sendable (struct with Sendable properties): struct User: Sendable { let id: Int; let name: String } // Class must be explicitly Sendable (and thread-safe): final class ThreadSafeCounter: @unchecked Sendable { private var value = 0 private let lock = NSLock() func increment() { lock.lock(); defer { lock.unlock() }; value += 1 } } // Actor is Sendable: actor DataStore: Sendable { var data: [String] = [] }. Actor isolation: actor state can only be accessed from within the actor (or via await): actor UserCache { private var cache: [Int: User] = [:] func store(_ user: User) { cache[user.id] = user } func user(id: Int) -> User? { cache[id] } } let cache = UserCache() // From outside actor -- must await: let user = await cache.user(id: 42) // Inside actor (on actor) -- no await: extension UserCache { func clearExpired(before date: Date) { // Direct access -- no await needed cache = cache.filter { _, user in user.expiry > date } } }. Global actors: @globalActor actor NetworkActor { static let shared = NetworkActor() } @NetworkActor class NetworkManager { func fetch() async throws -> Data { /* isolated to NetworkActor */ } }. Swift 6 strict concurrency: the compiler checks for all Sendable violations and actor isolation at compile time — data races become compile errors rather than runtime crashes.
Previous
What is Swift's type system — protocols with associated types and existentials?
Next
What are Swift macros?