Что гарантирует атомарность операций и как её обеспечить в iOS?

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

Ответ

Атомарность гарантирует, что операция выполнится целиком (все её побочные эффекты будут видны) или не выполнится вообще (состояние системы не изменится). Промежуточные состояния операции недоступны для других потоков.

Механизмы обеспечения атомарности в iOS/macOS:

  1. Атомарные операции процессора (CAS):

    • Низкоуровневые инструкции типа Compare-And-Swap.
    • В Swift: пакет Swift Atomics.
      import Atomics
      let atomicCounter = ManagedAtomic<Int>(0)
      atomicCounter.wrappingIncrement(by: 1, ordering: .relaxed)
  2. Барьеры (barriers) в Grand Central Dispatch:

    • Гарантируют, что задачи в concurrent очереди выполнятся атомарно относительно других задач.
      
      let concurrentQueue = DispatchQueue(label: "com.example", attributes: .concurrent)
      var internalData: [String] = []

    func atomicallyUpdateData(_ newValue: String) { concurrentQueue.async(flags: .barrier) { // Этот блок выполняется эксклюзивно internalData.append(newValue) } }

  3. Транзакции в Core Data / базах данных:

    • Группа изменений сохраняется (save()) или полностью откатывается (rollback()).
  4. Мьютексы и семафоры (os_unfair_lock, NSLock):

    • Позволяют сделать критическую секцию кода атомарной.

Важное уточнение: Атомарность не решает все проблемы многопоточности. Она гарантирует неделимость одной операции, но для корректной работы с ресурсами часто нужны более высокоуровневые примитивы синхронизации (очереди, акторы) для управления последовательностью операций.