Что такое async/await в Swift?

«Что такое async/await в Swift?» — вопрос из категории Многопоточность, который задают на 33% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

async/await — это модель асинхронного программирования в Swift, которая позволяет писать последовательный, легко читаемый код для асинхронных операций, заменяя цепочки completion handlers ("callback hell").

Основные концепции:

  • async — ключевое слово, которым помечается асинхронная функция. Такая функция может быть приостановлена.
  • await — ключевое слово, указывающее точку, где выполнение может быть приостановлено до завершения асинхронной операции. Поток при этом не блокируется.
  • Task — единица работы, в которой выполняется асинхронный код.

Пример:

// Асинхронная функция для загрузки данных
func fetchUserData() async throws -> User {
    let url = URL(string: "https://api.example.com/user")!
    // `await` приостанавливает функцию, пока данные не будут загружены
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

// Вызов асинхронной функции
Task {
    do {
        let user = try await fetchUserData()
        await MainActor.run {
            // Обновление UI должно происходить на главном потоке
            self.updateUI(with: user)
        }
    } catch {
        print("Failed to fetch user: (error)")
    }
}

Преимущества:

  • Улучшенная читаемость: Код выглядит как синхронный.
  • Упрощенная обработка ошибок: Используется привычный механизм try/catch.
  • Безопасность: Компилятор помогает избежать распространенных ошибок (например, вызов асинхронного кода не из асинхронного контекста).

Важные нюансы:

  • Нативно поддерживается с iOS 15, macOS 12, tvOS 15, watchOS 8.
  • Для обратной совместимости с более старыми API используется withCheckedContinuation.
  • Для работы с главным потоком используется MainActor.