Ответ
GCD — низкоуровневый API для управления многопоточностью в iOS. Использовал для асинхронных операций и параллельных вычислений.
Основные компоненты:
-
Очереди (DispatchQueue):
// Создание кастомной очереди let queue = DispatchQueue( label: "com.example.queue", qos: .userInitiated, attributes: .concurrent ) queue.async { /* Асинхронная задача */ } -
Глобальные очереди с приоритетами:
DispatchQueue.global(qos: .background).async { // Фоновая задача DispatchQueue.main.async { // Обновление UI } } -
Группы (DispatchGroup) для синхронизации:
let group = DispatchGroup() for task in tasks { group.enter() task.execute { group.leave() } } group.notify(queue: .main) { print("Все задачи завершены") } -
Барьеры для потокобезопасности:
concurrentQueue.async(flags: .barrier) { // Эксклюзивный доступ для записи }
Практическое применение:
- Оптимизация тяжелых вычислений
- Работа с сетью
- Синхронизация доступа к общим ресурсам
- Отложенное выполнение через
asyncAfter
Ответ 18+ 🔞
О, GCD, ёпта! Ну это же классика, блядь, наше всё для iOS-разработчика! Без этого никуда, как без рук, сука. Сейчас расскажу, что к чему, только не усни.
Вот смотри, GCD — это такой низкоуровневый движок, который умеет хуярить задачи по потокам, как горячие пирожки. Нужен он, чтобы твоё приложение не зависало, пока что-то там грузится или считает, а пользователь мог дальше скроллить котиков, блядь.
Основные кирпичики, из которых это всё собрано:
- Очереди (DispatchQueue) — это как конвейеры на заводе. Можно взять готовый, а можно свой сварганить, если хочешь особого подхода.
// Вот так свой конвейер делаешь, с блэкджеком и QoS'ом
let queue = DispatchQueue(
label: "com.example.queue", // Имя, чтобы в дебагере не сойти с ума
qos: .userInitiated, // Приоритет: "сделай побыстрее, пользователь ждёт!"
attributes: .concurrent // Атрибут: "можно несколько задач сразу гнать"
)
queue.async { /* И поехала асинхронная задача, пока основной поток не дрыхнет */ }
- Глобальные очереди — это как общественный транспорт, уже готовые маршруты. Бери и пользуйся, не парься созданием.
// Садишь задачу в фоновый автобус
DispatchQueue.global(qos: .background).async {
// Тут она едет, никому не мешая: качает файлы, парсит JSON, хуярит вычисления
// А как доедет...
DispatchQueue.main.async {
// ...пересаживается на главный поток-маршрутка
// И обновляет интерфейс, потому что с UI можно работать ТОЛЬКО отсюда!
// Иначе — креш, пиздец и слезы.
}
}
- Группы (DispatchGroup) — для тех, кто любит контролировать бардак. Ну типа, запустил кучу асинхронных тасков, а тебе надо понять, когда все они, суки, закончатся.
let group = DispatchGroup() // Создал надзирателя
for task in tasks {
group.enter() // Сказал: "Так, один чувак зашёл на задание!"
task.execute {
group.leave() // А тут он вышел и доложил: "Я всё, свободен!"
}
}
// И вот когда все доложили, что свободны...
group.notify(queue: .main) {
print("Все задачи завершены, можно выдохнуть") // ...получаешь оповещение на главной.
}
- Барьеры — это твой сантехник в мире потоков. Нужны, когда у тебя concurrent очередь (та, где задачи бегают одновременно), но в какой-то момент надо наглухо перекрыть воду и сделать что-то одно, без свидетелей.
concurrentQueue.async(flags: .barrier) {
// В этот момент все остальные задачи в этой очереди встают в позу "руки за голову"
// И ждут, пока тут закончится. Идеально для записи в общий ресурс,
// чтобы не получилось каши из данных, блядь.
}
А где это всё, блядь, применять-то?
- Тяжёлые вычисления (типа обработки фото или сложной математики) — выкидываешь на глобальную очередь с приоритетом
.utilityили.background, чтобы интерфейс не дёргался. - Сеть — вообще святое дело. Весь сетевой запрос — в фон, а колбэк с результатом — на главную, в UI.
- Общие ресурсы (какой-нибудь кэш в памяти) — читать можно с многих потоков, а писать — только через барьер, чтобы не угробить всё.
- Отложенный запуск — есть же
asyncAfter(deadline:). Хочешь через три секунды что-то сделать? Легко, блядь. Таймеры свои не нужно городить.
Вот такая, блядь, магия. Сначала кажется, что хуйня какая-то, а потом втягиваешься и без неё жить не можешь. Главное — не запутаться и не начать обновлять UI не из главной очереди, а то получишь креш такой, что мало не покажется.