Что означает main.sync в global(). Async означает?

В Swift я иногда использовал этот тип рисунка.

DispatchQueue.global().async {
    // do stuff in background, concurrent thread

    DispatchQueue.main.sync {
        // update UI
    }
}

Цель этого шаблона ясна. Делайте много времени для расчета в глобальном потоке, поэтому пользовательский интерфейс не блокируется и обновляет интерфейс в основном потоке после завершения расчета.

Что делать, если не рассчитывать? Я только что нашел логику в своем проекте, который

//A
DispatchQueue.main.sync {
    // do something
}

но

// B
DispatchQueue.global().async {
    DispatchQueue.main.sync {
        // do something
    }
}

не сбой.

Как они отличаются? И есть ли случай B по-разному только с этим?

// C
DispatchQueue.main.async {
    // do something
}

И еще один вопрос. Я знаю, что основной поток является последовательной очередью, но если я запускаю несколько кодовых блоков в нескольких main.async, он работает как параллельная очередь.

DispatchQueue.main.async {
    // do A
}

DispatchQueue.main.async {
    // do B
}

Если основной поток действительно является последовательной очередью, как они могут работать одновременно? Если это всего лишь отрезок времени, чем то, как они отличаются от глобальной параллельной очереди, отличной от основного потока, можно обновить интерфейс?

Ответ 1

x.sync означает, что очередь вызовов приостанавливается и дождитесь окончания завершения блока синхронизации. поэтому в вашем примере:

DispatchQueue.global().async {
    // yada yada something
    DispatchQueue.main.sync {
        // update UI
    }
    // this will happen only after 'update UI' has finished executing
}

Обычно вам не нужно sync вернуться к основному, асинхронно, вероятно, достаточно хорошо и безопаснее, чтобы избежать взаимоблокировок. Если это не особый случай, когда вам нужно подождать, пока что-то не закончится на главном, прежде чем продолжить свою асинхронную задачу.

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

Что касается планирования нескольких блоков в основной очереди с помощью async: они не будут запускаться параллельно - они будут происходить один за другим. Также не предполагайте, что queue == thread. Планирование нескольких блоков в одной очереди может создать столько потоков, сколько позволит система. Просто главная очередь особенная, что в ней используется Основной поток.

Ответ 2

Очереди[More]

GCD предоставляет три основных типа очередей:

1. Основная очередь: работает на main thread и является serial queue.
2. Глобальные очереди: concurrent queues, которые являются общими для всей системы. Существует четыре таких очереди с разными приоритетами: высокий, по умолчанию, низкий и фоновый. Фоновая очередь с приоритетами имеет самый низкий приоритет и регулируется при любых операциях ввода-вывода, чтобы минимизировать негативное влияние на систему.
3. Пользовательские очереди: создаваемые вами очереди, которые могут быть serial or concurrent. Запросы в этих очередях фактически попадают в одну из глобальных очередей.

Резюме

В общем, вы хотите использовать async, когда вам нужно выполнить сетевую или ресурсоемкую задачу в фоновом режиме, а не блокировать текущий поток.

Вот краткое руководство о том, как и когда использовать различные очереди с async:

  • Основная очередь: Это обычный выбор для обновления пользовательского интерфейса после завершения работы над задачей в параллельной очереди. Для этого вы кодируете одно замыкание внутри другого. Ориентация на главную очередь и вызов async гарантирует, что эта новая задача будет выполнена через некоторое время после завершения текущего метода.
  • Глобальная очередь: Это обычный выбор для выполнения работы без пользовательского интерфейса в фоновом режиме.
  • Custom Serial Queue: Хороший выбор, когда вы хотите выполнять фоновую работу последовательно и отслеживать ее. Это исключает конфликт ресурсов и состояние гонки, поскольку вы знаете, что выполняется только одна задача за раз. Обратите внимание, что если вам нужны данные из метода, вы должны объявить другое закрытие для их извлечения или рассмотреть возможность использования sync.

Распространенная ошибка:

Вызовите DispatchQueue.main.sync из очереди main, в результате приложение будет заморожено, поскольку вызывающая очередь (main) будет ожидать завершения отправленного блока, но его (отправленный блок) даже не сможет запустить ( потому что очередь main была остановлена и ждет)

Источник здесь