Leave a rating/review
Throughout this course, whenever you’ve needed to make quick changes that drive the UI, you’ve called MainActor.run(...) to access MainActor from anywhere. Because your app runs on a single main thread, you can’t create a second or a third MainActor. So it does make sense that there’s a default, shared instance of that actor that you can safely use from anywhere.
There are other times you need an app-wide, single-instance shared state, for example:
- The app’s database layer is usually a singleton type that manages the state of a file on disk.
- Image or data caches are also often single-instance types.
- The authentication status of the user is valid app-wide, whether they have logged in or not.
Luckily, Swift allows you to create your own global actors, just like MainActor, for situations where you need a single, shared actor that’s accessible from anywhere.
@globalActor actor ImageDatabase {
static let shared = ImageDatabase()
// ...
}
Annotating an actor with the @globalActor attribute makes it automatically conform to the GlobalActor protocol. Its only requirement is a static property called shared to expose an actor instance that you make globally accessible. You don’t need to inject the actor from one type to another, or into the SwiftUI environment.
So how do you write code in your app, to work with singletons like databases or persistent caches?
@ImageDatabase func say(_ text: String) {
// ... automatically runs on ImageDatabase ...
}
To avoid data races, any method that accesses your global actor needs to run on it: You just annotate the method with the global actor.
@ImageDatabase class DiskStorage {
// ...
}
You can annotate a complete class with a global actor, and that will add that actor’s semantics to all its methods and properties (as long as they aren’t nonisolated).
You can use the @ annotation to group methods or entire types that can safely share mutable state in their own synchronized silo.
In the next episode, you’ll create a global actor you can use as a persistent image cache layer.