Actor in Swift

Actor is a concrete nominal type in Swift to tackle data synchronisation. They are reference types and can have methods, and properties, and also can implement protocols, but they don’t support inheritance which makes their initializers much simpler — there is no need for convenience initializers, overriding, the final keyword.

Actors are created using the new actor keyword. They can protect the internal state through data isolation ensuring that only a single thread will have access to the underlying data structure at a given time. All actors implicitly conform to a new Actor protocol; no other concrete type can use this. Actors solve the data race problem by introducing actor isolation. Stored properties cannot be written from outside the actor object at all.

If you are writing code inside an actor’s method, you can read other properties on that actor and call its synchronous methods without using await, but if you’re trying to use that data from outside the actor await is required even for synchronous properties and methods.

MainActor is a global actor that allows us to execute code on the main queue. Using the keyword @MainActor global actor you can use to mark properties and methods that should be accessed only on the main thread. It is a global actor wrapper around the underlying MainActor struct, which is helpful because it has a static run() method that lets us schedule work to be run.

Actors in Swift are a great way to synchronize access to a shared mutable state which prevents data race. Async-await in Swift allows for structured concurrency, which will improve the readability of complex asynchronous code. We can easily avoid closures with self-capturing and improve error handling.