1. What is Swift Concurrency?
Swift Concurrency is Apple's modern asynchronous programming model introduced in Swift 5.5.
Swift concurrency is a built-in language model that allows apps to perform multiple tasks simultaneously—such as running background calculations or fetching network data—without blocking the main user interface.
Features:
async/await
Task
TaskGroup
Actor
Structured Concurrency
Benefits:
Cleaner code
Better readability
Thread-safe programming
Less callback nesting
2. What is async?
Marks a function that can suspend execution.
func fetchUsers() async -> [User] {
return []
}
// Call using:
let users = await fetchUsers()
3. What is await?
await waits for an async operation to complete.
let data = await apiService.fetchData()
It suspends the current task, not the thread.
Interview Point:
- await does not block the thread.
- It suspends the task.
4. Difference Between Async and Sync?
Sync
let data = service.fetchData()
print(data)
Execution waits.
Async
let data = await service.fetchData()
Task suspends and thread is free for other work.
5. What is a Task?
A unit of asynchronous work.
Task {
let users = await fetchUsers()
}
Creates a new concurrent task.
Q: Does Task {} run on the main thread?
A: Not always. Task {} inherits the current actor context. If it's created inside a @MainActor context, it executes on the Main Actor. Otherwise, Swift Concurrency schedules it on an appropriate thread, and there is no guarantee it will run on the main thread.
Task {} inherits the current actor context. If created inside @MainActor, it runs on MainActor. Otherwise, there is no guarantee which thread executes the task.
@MainActor
class MyViewModel {
func updateUI() {
Task {
print(Thread.isMainThread) // true
}
}
}
or
class MyViewModel {
@MainActor
func updateUI() {
Task {
print(Thread.isMainThread) // true
}
}
}
✅ Task {} inherits the @MainActor context.
The task starts on the Main Actor, so UI updates are safe.
Example:
@MainActor
func loadData() {
Task {
// Main Actor
title = "Loading..."
}
}
func fetchData() {
Task {
// Not guaranteed Main Thread
let data = await api.fetch()
}
}
A common interview follow-up:
Task {
print(Thread.isMainThread) // true
let data = await api.fetch()
print(Thread.isMainThread) // may be true or false
}
After an await, the task is guaranteed to resume on the same actor (if actor-isolated), but not necessarily on the same physical thread. Actor ≠ Thread. This distinction is very important in Swift Concurrency interviews.
func loadData() async {
print("fetch...")
}
Task {
await loadData()
}
From this code alone, we cannot determine whether it runs on the main thread.
Scenario 1: Created from MainActor
@MainActor
func buttonTapped() {
Task {
await loadData()
}
}
Here Task {} inherits @MainActor.
Top comments (0)