Ответ 1
Вы всегда будете получать 1, 2, 4, 3. 5 всегда будут после 1. Но там, где это заканчивается по отношению к другим, зависит от того, в какой очереди все началось.
Если это начато из основной очереди, то 5 всегда будет между 1 и 2.
Вот почему:
Этот код запускается в основной очереди. 1. Затем вы устанавливаете другой блок для асинхронного запуска в главной очереди, чтобы блок выполнялся после завершения текущего блока, а главная очередь доходила до конца текущего цикла цикла. Код продолжает следующую строку, которая должна печатать 5. Текущий блок завершается, и выполняется следующий блок в главной очереди. Это блок первого вызова DispatchQueue.main.async
. Поскольку этот блок работает, он печатает 2 (так что теперь у нас есть 1 5 2). Другой блок помещается в очередь в основную очередь, как и в предыдущей. Текущий блок продолжается и печатает 4 (так что теперь у нас есть 1 5 2 4). Блок завершается, и выполняется следующий блок в главной очереди. Это заключительный блок, который мы добавили. Этот блок работает, и он печатает 3, давая окончательный результат 1 5 2 4 3.
Если вы начали с некоторой фоновой очереди, то 5 может появиться где-то после 1, но для такого простого кода 5, скорее всего, все еще будут отображаться между 1 и 2, но он может появиться где угодно после 1 в общем случае.
Вот почему:
Этот код начинается в фоновом режиме. 1. Затем вы устанавливаете другой блок для асинхронного запуска в основной очереди, чтобы блок выполнялся после завершения цикла запуска текущей основной очереди. Код продолжает следующую строку, которая должна печатать 5. Текущий блок заканчивается. Блок, добавленный в основную очередь, запускается параллельно фоновой очереди. В зависимости от времени запуска блока, добавленного в основную очередь, по отношению к оставшемуся коду в фоновом режиме, вывод print("5")
может смешиваться с отпечатками из основной очереди. Вот почему 5 могут появиться где-то после 1, когда они начинаются с фона.
Но простой код в вопросе, скорее всего, всегда даст 1 5 2 4 3 даже при запуске на фоне, потому что код настолько короткий и занимает так мало времени.
Здесь некоторый код, который помещает 5 в другом месте:
func asyncTest() {
print("1")
DispatchQueue.main.async {
print("2")
DispatchQueue.main.async {
print(3)
}
print("4")
}
for _ in 0...1000 {
}
print("5")
}
DispatchQueue.global(qos: .background).async {
asyncTest()
}
Существование цикла приводит к тому, что 5 займет немного больше времени, прежде чем появится, что позволяет основной очереди выполнить кадровый процесс до того, как будет напечатано 5. Без цикла фоновый поток выполняется слишком быстро, так что 5 появляется перед 2.
Если вы используете этот тест на игровой площадке, добавьте:
PlaygroundPage.current.needsIndefiniteExecution = true
на вершину игровой площадки (сразу после импорта). Вам также понадобятся:
import PlaygroundSupport