Skip to content
DeveloperMemos

Using @MainActor in Swift

Swift, Concurrency, @MainActor1 min read

Concurrency is a common problem in software development, and Swift offers some powerful tools to help us deal with it. One of these tools is the @MainActor attribute, which was introduced in Swift 5.5. This attribute can be applied to a property or method, and specifies that it should be executed on the main thread, ensuring thread-safety and avoiding concurrency issues.

Let's take a look at how to use the @MainActor attribute in Swift.

Using @MainActor

Suppose we have a class with a property that needs to be accessed from multiple threads:

1class MyClass {
2 var myProperty: String = ""
3}

If we access myProperty from multiple threads, we may run into concurrency issues. To avoid this, we can mark the property with the @MainActor attribute:

1class MyClass {
2 @MainActor var myProperty: String = ""
3}

This ensures that any access to myProperty will be executed on the main thread.

We can also mark a method with the @MainActor attribute to ensure that it is executed on the main thread:

1class MyClass {
2 @MainActor func doSomething() {
3 // This method will be executed on the main thread
4 }
5}

In this example, doSomething() will always be executed on the main thread, regardless of which thread it is called from.

Example

Let's take a look at a more practical example. Suppose we have a view controller that needs to update a label with some text:

1class ViewController: UIViewController {
2 @IBOutlet weak var myLabel: UILabel!
3
4 func updateLabel(text: String) {
5 myLabel.text = text
6 }
7}

If we call updateLabel(text:) from a background thread, we may run into concurrency issues. To avoid this, we can mark the method with the @MainActor attribute:

1class ViewController: UIViewController {
2 @MainActor
3 func updateLabel(text: String) {
4 myLabel.text = text
5 }
6}

This ensures that any calls to updateLabel(text:) will be executed on the main thread, avoiding any concurrency issues.

Conclusion

The @MainActor attribute is a powerful tool for dealing with concurrency issues in Swift. By marking a property or method with this attribute, we can ensure that it is always executed on the main thread, avoiding any concurrency issues and ensuring thread-safety.

It's important to note that the @MainActor attribute is only available in Swift 5.5 and later. If you're using an earlier version of Swift, you'll need to use other concurrency tools, such as locks or serial queues, to ensure thread-safety.