Actors and isolated mutable state
Actors and isolated mutable state
Several tasks may need to update one attendance register. An actor protects access to its isolated mutable state through Swift’s concurrency rules. This gives a place to organize coordinated state changes instead of sharing an unrestricted mutable class everywhere.
What you’ll learn
- Access isolated register state through awaited operations.
- Explain why suspension does not make a multi-step workflow atomic.
Actors and isolated mutable state in the example
Isolated register
Several tasks may need to update one attendance register.
Isolated registerAwaited updates
Access to actor-isolated operations from outside generally requires await because another operation may be in progress.
Awaited updatesRead total safely
The two awaited arrivals are completed before reading the total, so the result is two.
Read total safely
How actors and isolated mutable state works
Access to actor-isolated operations from outside generally requires await because another operation may be in progress. A method with no suspension can update its isolated state as one uninterrupted actor operation, but an actor method can be reentered around suspension points. Actors do not make a multi-await workflow an automatic transaction.
Work through actors and isolated mutable state
Save this complete program as main.swift and run it with the Swift toolchain. Use a toolchain supporting the demonstrated async top-level code.
Swift · complete program
actor Register {
private var count = 0
func recordArrival() { count += 1 }
func total() -> Int { count }
}
let register = Register()
await register.recordArrival()
await register.recordArrival()
print(await register.total())Expected output
2Follow the execution
The two awaited arrivals are completed before reading the total, so the result is two. State is private to the actor. This example intentionally orders the calls rather than relying on unpredictable concurrent print statements.
Try this program in the Swift compiler. Paste the complete source above.
Practice: Actors and isolated mutable state
Your task: Does actor isolation guarantee state stays unchanged across every await inside a longer method?
Swift · complete program
actor Register {
private var count = 0
func recordArrival() { count += 1 }
func total() -> Int { count }
}
let register = Register()
await register.recordArrival()
await register.recordArrival()
print(await register.total())Worked answer
No. Suspension can allow another operation to enter the actor and change state. Recheck assumptions or design a single non-suspending update when a decision must use consistent state.
Recheck assumptions across suspension
Sendable expresses values suitable for crossing concurrency boundaries under their type rules. MainActor is a specific global actor commonly used for UI-related state, not a general instruction to put every operation on the main thread. Keep blocking work out of an actor’s cooperative execution path.
Check your decision
Check the practical consequence
Recheck assumptions across suspension
No. Suspension can allow another operation to enter the actor and change state. Recheck assumptions or design a single non-suspending update when a decision must use consistent state. Sendable expresses values suitable for crossing concurrency boundaries under their type rules.
Further reading: official Swift language guide.
Reaching the recap and completing the quizzes are separate milestones.