Планировщики и потоки выполнения
Управляйте выполнением с помощью receive(on:) и subscribe(on:).
«Планировщики и потоки выполнения» — бесплатный урок Swift Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Планировщики в Combine
Планировщик в Combine определяет, когда и где выполняется работа: какой поток или очередь запускает операторы и доставляет значения подписчикам.
Управление планировщиками необходимо, чтобы обновления пользовательского интерфейса выполнялись в главном потоке, а тяжёлая работа — за его пределами.
Два ключевых оператора
Combine предоставляет два оператора для управления потоками выполнения:
- subscribe(on:) — определяет, где начинается подписка и работа upstream
- receive(on:) — определяет, где доставляются значения downstream
Они управляют разными концами конвейера.
receive(on:)
receive(on:) перемещает всё, что идёт после него, на указанный планировщик. Чаще всего его используют, чтобы вернуться в главную очередь перед обновлением пользовательского интерфейса.
apiClient.fetchUser(id: 1)
.receive(on: DispatchQueue.main)
.sink { user in
self.nameLabel.text = user.name
}
.store(in: &cancellables)subscribe(on:)
subscribe(on:) определяет поток выполнения, в котором publisher начинает выдавать значения, а также поток для работы операторов upstream. Используйте его, чтобы перенести дорогостоящую настройку из главного потока.
heavyPublisher
.subscribe(on: DispatchQueue.global(qos: .userInitiated))
.receive(on: DispatchQueue.main)
.sink { result in
self.update(result)
}
.store(in: &cancellables)subscribe(on:) и receive(on:)
Запомните направление:
- subscribe(on:) влияет на upstream — место, где начинается работа
- receive(on:) влияет на downstream — место доставки результатов
Обычно subscribe(on:) используют для фоновой работы, а receive(on:) — для доставки в главный поток.
DispatchQueue как планировщик
DispatchQueue соответствует протоколу Scheduler. DispatchQueue.main доставляет значения в главный поток, а очереди global выполняют работу параллельно в background.
let background = DispatchQueue.global(qos: .background)
publisher
.map { expensiveTransform($0) }
.subscribe(on: background)
.receive(on: DispatchQueue.main)
.sink { self.render($0) }
.store(in: &cancellables)RunLoop как планировщик
RunLoop — ещё один планировщик, связанный с циклом обработки событий потока. RunLoop.main доставляет значения в координации с событиями пользовательского интерфейса, что может быть важно, например, для плавности прокрутки.
timerPublisher
.receive(on: RunLoop.main)
.sink { _ in
self.tick()
}
.store(in: &cancellables)DispatchQueue и RunLoop
Оба планировщика могут доставлять значения в главный поток, но между ними есть тонкие различия:
- DispatchQueue.main — планирует работу даже во время отслеживания прокрутки
- RunLoop.main — откладывает работу, пока цикл обработки событий находится в режиме отслеживания
Для большинства обновлений пользовательского интерфейса после асинхронной работы безопаснее использовать DispatchQueue.main по умолчанию.
Операторы времени планировщика
Такие операторы, как debounce, throttle и delay, принимают аргумент-планировщик, который определяет, какая очередь отвечает за отсчёт времени.
searchTextPublisher
.debounce(for: .milliseconds(300), scheduler: DispatchQueue.main)
.sink { query in
self.runSearch(query)
}
.store(in: &cancellables)Распространённая ошибка при работе с потоками
Обновление пользовательского интерфейса не в главном потоке приводит к сбоям или визуальным дефектам. Если после publisher, работающего в background, забыть добавить receive(on: DispatchQueue.main), Ваш sink может выполняться в фоновом потоке.
Всегда доставляйте значения, предназначенные для пользовательского интерфейса, через главный планировщик.
Собираем всё вместе
Надёжный конвейер запускает работу в background, обрабатывает данные там, а затем доставляет результат в главный поток для отображения.
imageURLPublisher
.subscribe(on: DispatchQueue.global())
.flatMap { url in downloadImage(url) }
.map { resize($0) }
.receive(on: DispatchQueue.main)
.sink { self.imageView.image = $0 }
.store(in: &cancellables)Быстрая проверка
Проверьте свои знания о планировщиках.
Итоги
Вы научились управлять потоками выполнения в Combine:
- subscribe(on:) — место начала работы upstream
- receive(on:) — место доставки результатов
- DispatchQueue и RunLoop в роли планировщиков
- Всегда доставляйте обновления пользовательского интерфейса в главный поток
Правильное планирование сохраняет отзывчивость приложений и предотвращает сбои.
Часто задаваемые вопросы
Урок «Планировщики и потоки выполнения» бесплатный?
Да — полный текст урока «Планировщики и потоки выполнения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Планировщики и потоки выполнения»?
Управляйте выполнением с помощью receive(on:) и subscribe(on:). Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Планировщики и потоки выполнения»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Преобразование и объединение потоков
- Планировщики и потоки выполнения
- Операторы обработки ошибок
- Пользовательские издатели и подписчики