Comments 13
А точно код становится многопоточным , в Swift асинхронность = многопоточность?
Гораздо интереснее было бы рассмотреть, чем он хуже GCD, так как про лучшесть и так из каждой трубы слышно.
Приоритет тасок теперь важен, так как исполняются они не в FIFO, как в GCD. Это может сбить с толку кучу народу, кто всю жизнь писал под GCD/Combine и не трогал треды. Apple на этой важнейшей детали вообще не заострил внимание
Акторы обманчиво похожи на обычный джавный монитор на самом объекте (или, если вы из мира ios, на serial queue по заходу в метод), но на самом деле критическая секция длится лишь до suspend'а. На деле это значит, то любые isolated-методы у акторов надо делать с пониманием, что зайти в метод может много клиентов сразу, но исполняется только один за раз. Это, опять же, контринтуитивно и упоминается Apple лишь вскользь
Таски захватывают свой контекст сильно до конца исполнения, даже если написать [weak self]. В интернете об этом знают полторы статьи - в итоге память течет нещадно (но, к счастью, утечки чаще всего временные). Опять же, контринтуитивно и в разрез с устоявшимся синтаксисом остального языка
Чтобы таски тестировать в юнит тестах, их приходится открывать как private(set), так как свои Executor эппл писать не разрешила. В итоге из каждого объекта торчит лишняя переменная, а тесты ходят по другим потокам даже для возвращения мок-данных, так как нельзя заставить все идти серийно, синхронно на один тред (как с GCD делалось через собственную абстракцию над DispatchQueue).
Добавлю еще один пункт к списку:
Если мы работаем с большим количеством потокоблокирующих тасок, то GCD будет отрабатывать такие случаи быстрее чем async/await. Например, если в async варианте функции из примера про Thread Explosion заменить
Task.sleep
на просто блокирующийsleep
, то GCD вариант выполнится быстрее. Это происходит из-за того что в Cooperative Thread Pull выделяется ограниченное кол-во потоков, и при блокировке они быстро заканчиваются.
Спасибо за статью. В тексте ниже наверное опечатка и имелось в виду «Все наши очереди последовательные (serial)». А то формулировка «асинхронные» вводит в заблуждение.
«Все наши очереди синхронные, высокоприоритетная задача добавилась в очередь самой последней, следовательно ей нужно подождать пока выполнятся все предыдущие таски из background
очереди»
Новая модель работы с многопоточкой async/await абстрагирует разработчика от понятий потоков и очередей. Новая модель включает в себя Cooperative Thread Pull, который инкапсулирует всю логику по работе с потоками и очередями.
Cooperative Thread Pool, паттерн такой https://en.wikipedia.org/wiki/Thread_pool
Почему в примере с try/catch не показана обработка ошибок в сравнении с вариантом на лямбда функциях?
Насколько я понял вы говорите про функцию ниже (поправьте если я не так понял)
func loadAndProcessImage(from url: URL) async throws -> UIImage {
let image = try await loadImage(from: url)
let blurredImage = try await applyBlurFilter(to: image)
try await cacheToDisk(blurredImage)
return blurredImage
}
Тут нет обработки ошибок с помощью catch, так как подразумевается что обработка будет происходить в месте вызова данной функции (она сама по себе throws
)
Swift async/await. Чем он лучше GCD?