Какие инструменты для многопоточности доступны в iOS/macOS?

«Какие инструменты для многопоточности доступны в iOS/macOS?» — вопрос из категории Многопоточность, который задают на 49% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основные инструменты для работы с многопоточностью в экосистеме Apple:

  1. Grand Central Dispatch (GCD / libdispatch): Низкоуровневый C-фреймворк для управления очередями задач.

    • Очереди: DispatchQueue (serial, concurrent), DispatchGroup, DispatchSemaphore.
    • Пример:
      // Отправка задачи в фоновую очередь
      DispatchQueue.global(qos: .userInitiated).async {
      let result = performHeavyCalculation()
      // Возврат результата в главный поток для обновления UI
      DispatchQueue.main.async {
          updateUI(with: result)
      }
      }
  2. OperationQueue: Высокоуровневая абстракция на основе GCD. Позволяет создавать переиспользуемые Operation с зависимостями, приоритетами и возможностью отмены.

    let queue = OperationQueue()
    queue.maxConcurrentOperationCount = 2
    
    let downloadOp = BlockOperation { /* Загрузка данных */ }
    let processOp = BlockOperation { /* Обработка данных */ }
    processOp.addDependency(downloadOp) // Обработка начнется только после загрузки
    
    queue.addOperations([downloadOp, processOp], waitUntilFinished: false)
  3. Swift Concurrency (async/await): Современный, безопасный подход, представленный в Swift 5.5.

    • Ключевые элементы: async/await, Task, Actor.
    • Пример:
      
      func fetchData() async throws -> Data {
      let (data, _) = try await URLSession.shared.data(from: url)
      return data
      }

    Task { let data = try await fetchData() await MainActor.run { updateUI(with: data) } }

  4. Средства синхронизации: Для защиты общих ресурсов от состояний гонки.

    • NSLock, os_unfair_lock (более эффективный).
    • @Atomic свойства (через property wrappers).
    • Актёры (Actors) в Swift Concurrency.

Рекомендация: Для нового кода предпочтительно использовать Swift Concurrency, так как он обеспечивает безопасность на уровне компилятора и более читаемый код.