@MainActor in Swift — Detailed walkthrough
DispatchQueue.main.async will no longer be required to update UI elements in Main Thread. Latest Swift’s @MainActor will replace that and make our coding easier and easy to understand.
@MainActor in Swift is an interesting addition in Swift 5.5. I would suggest reading my article Actor in Swift, if you are not familiar with Actor in Swift yet. Because understanding the Actor will make you understand @MainActor better. In short, Swift concurrency programming is taken to next level by introducing Actor in Swift. Swift Actors help us to access the data without having data race issues by having them in a queue/thread by eliminating our manual boilerplate code.
Use of Swift’s @MainActor:
Now, let’s dive into the use case. We have our typical case, where we get the data from the server or from local db in the background or new thread and post that we will update them in our UI components. Below is the sample screenshot.

In the above code snippet, we have an issue. Because our label is getting updated in the background thread. What will happen? We will get this warning and a crash when we run this code.


So, to solve this, we use to call that method from DispatchQueue.main.async { } as below.

This works fine. But, sometimes we use to forget to call this method from Dispatch main Queue and it has to be done everywhere we perform this similar operation.
What is @MainActor in swift:
So, the latest swift concurrency programming brings @MainActor to make this simple and more effective. Again, I would like to repeat, if you are not familiar, please read my article on Actor in Swift for better understanding

If we observe the above screenshot, @MainActor is the attribute we added in the function declaration and removed DispatchQueue.main.async. Meaning that, this function will be executed in the main thread automatically by transforming this operation to the main thread. Swift does it for us in the latest concurrency system. So cool!!!. This helps us to remove the repeated code and reduces our human mistakes.
This main actor in Swift performs all its operations in main thread. Apple uses them explicitly in UIKit, SwiftUI and more…
Class with @MainActor:
We can declare a complete class as @MainActor, having said that, the properties and methods are in that class will get executed in the main thread. The below screenshot marks our viewmodel class with @MainActor attribute. So, all the methods and properties are now streamed into the main thread.

We would have a question here correct, what if we have a method or a property that doesn’t need to be in the Main thread in this class. Yeah, we can mark them as “nonisolated”(a concept in Swift Actor).
How inheritance behaves on @MainActor.
Ok, we have a class and marked with @MainActor, what will happen if we inherit that class. As following the principle of least surprise, subclasses also will be @MainActor.
Overriding a @MainActor method will also become @MainActor method.
@MainActor usage in Protocols:
Let’s say, we have a protocol and it has a method with @MainActor attribute as below,

How it behaves actually, the class or any type confirms this protocol with the same method, that will also become @MainActor.

Let’s dive further into the protocol usage. Can we mark the complete protocol as @MainActor?. Yes, that's possible.

Ok, what would be the behaviour in different cases. 💁
A class or a type which confirms this protocol in main definition or declaration will become @MainActor completely, whereas if that class or struct or any other type confirm this protocol in an extension, Then only those methods becomes as @MainActor.
To make it clear, please refer to the below snapshot.


The same thing goes for other types like struct or enum etc.
That's all for now. Thanks for reading!!!. If you like my writeup and think to appreciate the hour and effort I spent on this article, please share this page with your colleagues/friends or clap me on this page.