main.async против main.sync() против global().async в Swift3 GCD

Пример A:- Это вызывает App Crash.

DispatchQueue.main.async {           
        let url = URL(string: imageUrl)
        do {
             let data = try Data(contentsOf: url!)
                DispatchQueue.main.sync {
                    self.imageIcon.image = UIImage(data: data)
                }
            }

Пример Б: - Но это не так

DispatchQueue.global().async {  
        let url = URL(string: imageUrl)
        do {
            let data = try Data(contentsOf: url!)
                DispatchQueue.main.sync {
                    self.imageIcon.image = UIImage(data: data)
                }
            }

Насколько мне известно,

  • x.sync означает выполнение действий в основном потоке / потоке пользовательского интерфейса, а x.async означает выполнение действий в фоновом потоке.
  • Глобальный означает выполнение чего-либо с параллельной очередью, т.е. параллельное задание.

Quest1: - Так почему мое приложение зависло, когда я выполнил задачу в фоновом потоке, т.е. main.async, а затем вызвал основной поток для обновления пользовательского интерфейса.

Quest2: - Есть ли разница в main.async & global(). Async.

3 ответа

Решение

Проще говоря, я прихожу к выводу, что -

  • Очередь - существует 3 типа очереди, т.е. 1 основная очередь, 4 глобальные очереди и любое количество пользовательских очередей.
  • Потоки - One is Main Thread и другие фоновые потоки, которые нам предоставляет система.

DispatchQueue.main.async

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

DispatchQueue.global (). Async вместе с global (). Sync

Это означает выполнение задачи в глобальной очереди с использованием фонового потока, а когда задача завершается, чем использование global (). Sync переносит работу из globalQueue в mainQueue, которая обновляется до пользовательского интерфейса.

Причина сбоя моего приложения

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

Grand Central Dispatch GCD работает в диспетчерских очередях DispatchQueue с порядком FIFO

DispatchQueue.<queue>.<sync/async> означает запустить <sync/async> задача по <queue>

очередь

main- последовательная очередь в основном потоке, которая используется для работы с UI

DispatchQueue.main

global()- параллельная очередь, разделяемая системой.global() метод передачи приоритета в задаче с использованием qos QoSClass (priority GlobalQueuePriority устарела): background, default, unspecified, userInitiated, userInteractive, utility

DispatchQueue.global()
DispatchQueue.global(qos: .background)

Пользовательская очередь: - serial или concurrent настраиваемая очередь

DispatchQueue(label: "serialQueue")
DispatchQueue(label: "concurrentQueue", attributes: .concurrent)        

синхронизация / асинхронность

sync - заблокировать текущий поток и ждать, когда он будет завершен в указанной очереди

async - не блокировать текущий поток и отправлять блок выполнения кода в указанную очередь

Общая ошибка:

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

[Синхронизация и асинхронизация]

В первом случае вы запускаете код на main а затем вы используете main.sync в основной теме. По сути, вы пытаетесь рассказать main очередь ждать себя - что, очевидно, чепуха и, следовательно, вызывает сбой.

Во втором случае вы запускаете код в фоновом потоке, а затем используете main.sync ждать, пока main поток может запустить блок, предоставленный в main.sync,

В общем, я бы использовал async и не sync все время, если только sync необходимо - и всегда синхронизировать один поток (DispatchQueue) с другим, никогда с тем же.

Вы смешивали термины sync/async и main/global.

Синхронизация - синхронное выполнение некоторой задачи (т. Е. Поток, который может быть основным / глобальным / любым другим потоком, будет ожидать завершения задачи)

Async - запускать некоторую задачу асинхронно (то есть поток, который может быть основным / глобальным / любым другим потоком, поместит задачу в очередь и продолжит выполнение следующих шагов за пределами вашего блока. Он не будет ждать)

Теперь давайте пошли один за другим в коде, который вылетал:
Давайте назовем несколько имен для наших тем, чтобы нам было легко их понять:
1) ThreadA - который встречает ваши операторы отправки (это также может быть основной поток, но для целей объяснения я чувствую себя лучше)
2) ThreadB - глобальный поток, который создается при отправке какого-либо задания.
3) ThreadMain - Основная тема

Пример А:
DispatchQueue.main.async - ThreadA приходит и выполняет этот оператор, помещает ваш блок в ThreadMain и переходит (с момента его асинхронности) к следующим шагам после блока.

Теперь давайте поговорим о ThreadMain, что он будет делать здесь. Так как ThreadMain получил блок (представленный ThreadA), он начинает выполнять шаг за шагом, и внезапно он видит "DispatchQueue.main.sync" и отправляет внутренний блок в ту же очередь TheradMain и сохраняет onnnnn waitggggg (начиная с его синхронизации). Так что буквально вы превращаете ThreadMain в тупиковую ситуацию.

Другие вопросы по тегам