0
0
Swiftprogramming~10 mins

Global actors (@MainActor) in Swift - Step-by-Step Execution

Choose your learning style9 modes available
Concept Flow - Global actors (@MainActor)
Define @MainActor function
Call function from main thread
Function runs on main thread
Update UI or shared resource safely
Return control to caller
This flow shows how a function marked with @MainActor runs on the main thread to safely update UI or shared resources.
Execution Sample
Swift
import SwiftUI

@MainActor
func updateLabel() {
    print("Updating UI on main thread")
}

Task {
    await updateLabel()
}
This code defines a function marked with @MainActor and calls it asynchronously to ensure it runs on the main thread.
Execution Table
StepActionThreadResultOutput
1Define function updateLabel() with @MainActorMainFunction ready
2Start Task to call updateLabel()BackgroundTask started
3Await updateLabel() callBackgroundSwitch to main thread
4Execute updateLabel() on main threadMainPrint statement runsUpdating UI on main thread
5Return from updateLabel()MainFunction completes
6Task completesBackgroundControl returns
💡 Task finishes after updateLabel() runs on main thread and prints output
Variable Tracker
VariableStartAfter Step 2After Step 4Final
updateLabel()DefinedCalled (await)Executed on main threadCompleted
Key Moments - 2 Insights
Why does updateLabel() run on the main thread even though Task starts on a background thread?
Because updateLabel() is marked with @MainActor, Swift automatically switches execution to the main thread before running it, as shown in step 3 and 4 of the execution_table.
What happens if we call updateLabel() without await inside Task?
You must use await to call an async @MainActor function; otherwise, the compiler will give an error. The await ensures the caller waits for the main thread switch, as seen in step 3.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, on which step does the code switch to the main thread?
AStep 2
BStep 3
CStep 4
DStep 5
💡 Hint
Check the 'Thread' column in execution_table row for step 3 showing 'Switch to main thread'
According to variable_tracker, what is the state of updateLabel() after step 4?
AFunction is defined but not called
BFunction is called but not executed
CFunction executed on main thread
DFunction completed and returned
💡 Hint
Look at variable_tracker row for updateLabel() after step 4
If we remove @MainActor from updateLabel(), what changes in the execution flow?
AFunction runs on background thread without switching
BFunction still runs on main thread automatically
CFunction cannot be called from Task
DFunction causes a compile error
💡 Hint
Without @MainActor, no automatic thread switch happens as shown in step 3 of execution_table
Concept Snapshot
@MainActor marks functions to run on the main thread.
Calls to @MainActor functions switch threads automatically.
Use await to call async @MainActor functions.
Ensures safe UI or shared resource updates.
Helps avoid threading bugs in Swift concurrency.
Full Transcript
This example shows a Swift function marked with @MainActor, which means it must run on the main thread. When we call this function inside a Task, which runs on a background thread, Swift automatically switches to the main thread before running the function. The execution_table traces each step: defining the function, starting the Task, switching threads, running the function, and completing the Task. The variable_tracker shows the function's state changes. Key moments clarify why the thread switch happens and the need for await. The visual quiz tests understanding of thread switching and function execution. Overall, @MainActor helps keep UI updates safe by running code on the main thread.