Что такое конкурентность (Concurrency) в iOS?

Ответ

Конкурентность (Concurrency) — это концепция одновременного выполнения нескольких задач. В iOS задачи могут выполняться параллельно на разных ядрах CPU или псевдопараллельно (с быстрым переключением контекста) на одном ядре. Основные инструменты: Grand Central Dispatch (GCD), OperationQueue и async/await.

Пример с очередью GCD:

let concurrentQueue = DispatchQueue(label: "com.example.queue", attributes: .concurrent)

concurrentQueue.async {
    print("Задача 1 началась")
    sleep(1)
    print("Задача 1 завершилась")
}

concurrentQueue.async {
    print("Задача 2 началась")
    sleep(2)
    print("Задача 2 завершилась")
}
// Вывод может быть: "Задача 1 началась", "Задача 2 началась", "Задача 1 завершилась", "Задача 2 завершилась"

Важные аспекты:

  • Порядок выполнения конкурентных задач не гарантирован.
  • Время выполнения задач может перекрываться.
  • Доступ к общим ресурсам (память, файлы) требует синхронизации (например, с использованием DispatchQueue.barrier, семафоров DispatchSemaphore или акторов).

Ответ 18+ 🔞

А, конкурентность! Ну это когда у тебя в программе всё бегает как тараканы по кухне после включения света, одновременно, блядь. В iOS это типа несколько дел сразу делается: либо на разных ядрах процессора по-честному, либо на одном, но так быстро переключаются, что кажется, будто всё сразу. Инструменты? Да их дохуя: GCD, OperationQueue и этот новый, async/await.

Смотри, вот тебе пример на GCD, чтоб понятно было, как эти задачи друг другу под ноги мешаются:

let concurrentQueue = DispatchQueue(label: "com.example.queue", attributes: .concurrent)

concurrentQueue.async {
    print("Задача 1 началась")
    sleep(1)
    print("Задача 1 завершилась")
}

concurrentQueue.async {
    print("Задача 2 началась")
    sleep(2)
    print("Задача 2 завершилась")
}
// Вывод может быть: "Задача 1 началась", "Задача 2 началась", "Задача 1 завершилась", "Задача 2 завершилась"

Видишь? Они стартанули почти вместе, а финишировали кто во что горазд. Порядок — хуй его знает, гарантий ноль, ёпта. Время выполнения у них может накладываться друг на друга, как пьяные в подъезде.

И вот тут главный подвох, на котором все и обжигаются, как дураки: доступ к общим ресурсам. Представь, две эти задачи лезут в одну и ту же переменную или файл. Это ж пиздец настанет, data race, неразбериха, всё полетит к чертям собачьим! Поэтому нужна синхронизация, блядь. Типа поставить регулировщика на перекрёстке. Используй для этого DispatchQueue.barrier, семафоры (DispatchSemaphore) или этих новых акторов. А то будет как в той истории — один пишет, другой стирает, и в итоге получается хуйня, а не программа.