Swift Actors: Manage Concurrency and Prevent Data Races

The conceptual model

Steven Curtis

--

Photo by Avel Chuklanov on Unsplash

Let’s take a look at Actors in Swift. They’re rather great, as they can help to solve data races.

Difficulty: Beginner | Easy | Normal | Challenging

This article has been developed using Xcode 14.2, and Swift 5.7.2

Prerequisites

It would be useful to have some idea about Actors in programming

Keywords and Terminology

actor: A role played by the user with respect to interacting with the system

Actors

Actors are a conceptual model used to deal with concurrency

They are similar to classes in OO languages. In swift they are also reference types, which means when we create Actors with the actor keyword which means a reference to the object is passed when the actor is assigned.

An actor is a conceptual model which has been imported into swift. In programming we use actors to deal with concurrency in the model computation world.

In Swift actor types have private state (cannot be modified by another actor) which means their state is protected from data races which can occur from concurrent access to mutable data.

Taking a look

A classic example of a non-thread safe class is a Counter. Something like the following:

final class Counter {
var count = 0

func inc() {
count += 1
}
}

let counter = Counter()

DispatchQueue.global().async {
for _ in 0..<1000 {
counter.inc()
}
}

DispatchQueue.global().async {
for _ in 0..<1000 {
counter.inc()
}
}

Thread.sleep(forTimeInterval: 1)
print(counter.count)

Which sometimes prints 1998, sometimes 2000, sometimes 1999. It’s not ideal as there is a data race occurring. I have previously used NSLock to solve this problem.

However, I can instead use actor to do so.

actor Counter {
private var value = 0

func next() -> Int {
let current = value
value = value + 1
return current
}

func total() -> Int {…

--

--