Swift Concurrencyは、async/await を使って同期コードのように読める非同期コードを書けるようにし、同時にコンパイラがデータ競合の安全性を強制します。Task が並行処理を開始し、actor が可変状態を保護し、@MainActor がUIコードがメインスレッドで実行されることを保証します。
await は**中断ポイント(suspension point)**を示します。関数はそこで一時停止して他の処理のためにスレッドを解放でき、待機した値の準備ができたら再開します。コールバックもスレッドのブロックもありません。
func loadProfile() async throws -> Profile {
let user = try await fetchUser() // suspends, thread reused
let posts = try await fetchPosts(user) // runs after user resolves
return Profile(user: user, posts: posts)
}
// Start async work from a sync context
Task {
let profile = try await loadProfile()
await MainActor.run { render(profile) } // UI update on main thread
}
actor はその可変状態へのアクセスを直列化します。一度に1つのタスクしか触れないため、ロックもデータ競合もありません。
actor ImageCache {
private var store: [URL: Image] = [:]
func image(for url: URL) -> Image? { store[url] } // isolated
func insert(_ img: Image, for url: URL) { store[url] = img }
}
@MainActor
final class ViewModel: ObservableObject { // all members run on main thread
@Published var title = ""
}
async let と TaskGroup は子タスクを並列に実行して一緒に待機します。親をキャンセルすると子もキャンセルされます。
async let a = fetchA() // both start immediately, in parallel
async let b = fetchB()
let (x, y) = try await (a, b)
@MainActor を付け忘れると「Publishing changes from background thread」の警告が出ます。Task { } はactorコンテキストを継承しますが、Task.detached は継承しません。控えめに使ってください。async/awaitは深くネストしたcompletion handler(「コールバック地獄」)を置き換え、コンパイラがビルド時にデータ競合を捕捉するようになりました。面接官は、あなたが中断ポイント、actor隔離、@MainActor を理解しているかを確認します。これらが現代のiOS並行処理を読みやすく安全にしているモデルです。
ジュニアからシニアまで、詳細な回答付きのIT面接質問ライブラリ。
寄付する