What is the purpose of the @MainActor attribute in Swift?
The @MainActor attribute ensures that the annotated code runs on the main thread, which is important for updating the user interface safely and avoiding concurrency issues.
Click to reveal answer
beginner
How does @MainActor help with UI updates in Swift concurrency?
It guarantees that UI updates happen on the main thread, preventing crashes or unexpected behavior caused by updating UI elements from background threads.
Click to reveal answer
beginner
What happens if you try to update UI elements from a background thread without using @MainActor?
Updating UI from a background thread can cause crashes or visual glitches because UI frameworks expect changes on the main thread only.
Click to reveal answer
beginner
How do you mark a Swift function to run on the main thread using concurrency features?
You add the @MainActor attribute before the function declaration to ensure it runs on the main thread.
Click to reveal answer
intermediate
Explain the difference between @MainActor and manually dispatching to the main queue.
@MainActor is a language-level feature that automatically manages execution on the main thread, making code cleaner and safer, while manually dispatching uses DispatchQueue.main.async and requires explicit calls.
Click to reveal answer
What does the @MainActor attribute guarantee in Swift concurrency?
ACode runs only once
BCode runs on the main thread
CCode runs in parallel on multiple threads
DCode runs on a background thread
✗ Incorrect
@MainActor ensures the code runs on the main thread, which is essential for UI updates.
Why should UI updates be done on the main thread?
ATo avoid UI crashes and glitches
BTo speed up the app
CTo use less memory
DTo run code in parallel
✗ Incorrect
UI frameworks require updates on the main thread to work correctly and avoid crashes.
Which Swift attribute helps you run a function on the main thread automatically?
A@MainActor
B@BackgroundActor
C@UIThread
D@AsyncMain
✗ Incorrect
@MainActor is the correct attribute to ensure main thread execution.
What is a common alternative to @MainActor for running code on the main thread?
AOperationQueue.background
BDispatchQueue.global.async
CThread.sleep()
DDispatchQueue.main.async
✗ Incorrect
Using DispatchQueue.main.async manually dispatches code to the main thread.
If a function is marked with @MainActor, what happens when you call it from a background thread?
AThe app crashes immediately
BThe function runs on the background thread anyway
CThe call is automatically switched to the main thread
DThe function runs twice
✗ Incorrect
Swift automatically switches execution to the main thread for @MainActor functions.
Describe why @MainActor is important for UI work in Swift concurrency.
Think about how UI updates must happen safely.
You got /4 concepts.
Explain how @MainActor compares to using DispatchQueue.main.async for UI updates.
Consider ease of use and safety.
You got /4 concepts.
Practice
(1/5)
1. What is the main purpose of using @MainActor in Swift UI programming?
easy
A. To create multiple threads for UI tasks
B. To speed up background data processing
C. To disable asynchronous programming
D. To ensure UI updates run on the main thread safely
Solution
Step 1: Understand the role of @MainActor
@MainActor marks code to run on the main thread, which is required for UI updates to avoid crashes or glitches.
Step 2: Compare options with this role
Only To ensure UI updates run on the main thread safely correctly states that @MainActor ensures UI updates run safely on the main thread. Other options describe unrelated or incorrect behaviors.
Final Answer:
To ensure UI updates run on the main thread safely -> Option D
Quick Check:
@MainActor = safe UI updates on main thread [OK]
Hint: Remember: @MainActor means UI code runs on main thread [OK]
Common Mistakes:
Thinking @MainActor speeds up background tasks
Confusing @MainActor with creating multiple threads
Believing @MainActor disables async programming
2. Which of the following is the correct way to declare a function that updates UI and must run on the main thread using @MainActor?
easy
A. @MainActor async func updateUI() { /* code */ }
B. @MainActor func updateUI() { /* code */ }
C. func updateUI() async @MainActor { /* code */ }
D. func updateUI() @MainActor { /* code */ }
Solution
Step 1: Recall correct syntax for @MainActor on functions
The attribute @MainActor must appear before the 'func' keyword. Swift uses postfix 'async' after parameters for asynchronous functions: @MainActor func updateUI() async { /* code */ }. For synchronous UI updates, @MainActor func updateUI() { /* code */ } is correct.
Step 2: Analyze each option
@MainActor async func updateUI() { /* code */ } uses invalid prefix 'async func' syntax. @MainActor func updateUI() { /* code */ } is correct for synchronous UI function on main thread. func updateUI() async @MainActor { /* code */ } misplaces @MainActor after 'async'. func updateUI() @MainActor { /* code */ } places @MainActor incorrectly after function name.
@MainActor before func keyword = correct syntax [OK]
Hint: @MainActor before func keyword for main thread UI functions [OK]
Common Mistakes:
Using invalid prefix 'async func' syntax from other languages
Placing @MainActor after function name or 'async'
Misordering keywords in function declaration
3. Consider this Swift code snippet:
@MainActor
class ViewModel {
var count = 0
func increment() {
count += 1
}
}
let vm = ViewModel()
Task {
await vm.increment()
print(vm.count)
}
What will be printed when this code runs?
medium
A. 1
B. 0
C. Compilation error
D. Runtime crash
Solution
Step 1: Understand @MainActor effect on ViewModel
The class is marked @MainActor, so all its properties and methods are main actor-isolated and require 'await' when accessed from non-isolated contexts like Tasks.
Step 2: Analyze the Task block
The Task calls await vm.increment(), which correctly hops to the main actor and increments count to 1. The print(vm.count) is inside the Task closure, which is asynchronous and runs on the main actor context, so accessing vm.count is allowed and will print 1.
Final Answer:
1 -> Option A
Quick Check:
Accessing @MainActor properties inside async Task after await is allowed [OK]
Hint: Use 'await' for @MainActor-isolated properties in Tasks [OK]
Common Mistakes:
Thinking print(vm.count) works and shows 1 after await increment
Assuming count stays 0 without proper isolation handling
Expecting runtime crash instead of compilation error
4. Identify the error in this Swift code using @MainActor:
class DataFetcher {
@MainActor
func fetchData() async {
// fetch data
}
}
let fetcher = DataFetcher()
Task {
await fetcher.fetchData()
}
medium
A. Cannot use @MainActor on a method inside a non-actor class
B. Missing async keyword on fetchData()
C. No error, code is correct
D. Must mark class as @MainActor, not just method
Solution
Step 1: Check @MainActor usage on method
Applying @MainActor to a method inside a normal class is allowed to ensure that method runs on main thread.
Step 2: Verify async and call correctness
The method is async and called with await inside a Task, which is correct usage.
Final Answer:
No error, code is correct -> Option C
Quick Check:
@MainActor on method in class is valid [OK]
Hint: You can mark methods @MainActor even in normal classes [OK]
Common Mistakes:
Thinking @MainActor only applies to classes
Forgetting async keyword on async methods
Assuming error without checking async/await usage
5. You have a SwiftUI app where a ViewModel class marked @MainActor updates a published property text. You want to fetch data asynchronously on a background thread and then update text safely on the main thread. Which approach correctly uses @MainActor to ensure safe UI updates?
hard
A. Mark the entire ViewModel as @MainActor and call async fetch on a background thread, then update text inside a @MainActor method
B. Do not use @MainActor; update text directly from any thread
C. Mark only the fetch method as @MainActor and update text without awaiting
D. Use DispatchQueue.global() to update text asynchronously
Solution
Step 1: Understand thread safety for UI updates
UI updates must happen on the main thread. Marking ViewModel as @MainActor ensures all its properties and methods run on main thread.
Step 2: Use async fetch on background thread and update on main thread
Fetching data can happen on background thread, but updating text must be done inside a @MainActor context, which is guaranteed if ViewModel is @MainActor.
Final Answer:
Mark the entire ViewModel as @MainActor and call async fetch on a background thread, then update text inside a @MainActor method -> Option A