Как стать автором
Обновить

Комментарии 32

Лет через пять будет актуально.

Приятное сообщество, в посте про разработку под iOS минусую люди далекие от этого.

Да, с учетом iOS 15, все это будет распространено очень нескоро

Большинство топ приложений которые делают кассу в AppStore, поддерживают iOS11/12, таким отношением эппл плюёт в колодец разработчикам этих приложений в лицо. Async/await нужно было внедрить ещё в swift 3 до stable abi, и не удивляться бурной дискуссии, ИМХО.

Пазл с минимальной поддерживаемой iOS 15, кажется, сложился.

Да как-то не особо. Ничего не мешало этот тред пул поставлять как библиотеку для старых iOS. Можно посмотреть на C#, где подобная практика повсеместна. Это ведь всего лишь тред пул, которому явно ничего хитрого не надо от самой iOS.

Выглядит все прям под копирку с C#. Особенно с этими всеми контекстами и тасками. Не сказать, что рад видеть очередные асинки, но наверное лучше, чем ничего. И в этом плане более интересны как раз акторы. Там свифт пытается быть безопасными наподобие раста.

Просто не понятно, почему они не смогли все это засунуть в более старые версии ios, тут конечно в этом плане kotlin выглядит победителем, на ios все это можно будет использовать ооочень не скоро

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

Только вот iOS 15 будет поддерживать 6s, которому в этом году 6 лет.

Вы ставили iOS 15 на 6s? iPad Air 2 даже браузер не тянет, при этом на iOS 13 летал, на 14 приемлемо работает, 15 увы.

Ожидаемо, но все же Эппл - не та компания, которая так уж прям заставляет покупать новое. Тестировать на старье по крайней мере можно:)

На старом SE стоит iOS 15. Работает вполне себе хорошо.

Поток, в котором выполнялся код до await, и который подхватил дальнейшее выполнение после, не обязательно будет одним и тем же.

То есть нет возможности "принудительно" заставить выполняться в том же потоке/ с тем же SynchronizationContext? По аналогу с ConfigureAwait(true) в шарпе?

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

Интересно, а тут async функции начинают исполняться до того момента, когда кто-то решил их awaitнуть или нет?

Да, в том случае, например, если была создана `async let` задача

Видимо, всё же, только в этом случае?

А в остальных — не начинают, пока их не await'нут.

Я читал, что вроде бы сам async/await будет работать в предыдущих версиях iOS, а вот для continuation нужна будет именно 15 версия - а теперь оказывается и сам async/await только на новой версии будет работать?

После SwiftUI vs Combine вы другого ожидали? Opaque Result Types была первая фича языка привязанная к версии ОС, и похоже поставили на поток, ждем babel для свифта.

Проще тогда уже PromiseKit использовать - это немного другой подход к асинхронности, но по крайней мере везде будет работать.

Этого следовало ожидать после того, как они решили рантайм свифта поставлять с iOS, а не с каждым приложением. Я конечно все понимаю, но можно было и другое решение придумать для большого размера приложений.

В предыдущих версиях iOS работать не будет, увы

upd: таки быть поддержке async/await в предыдщих версиях! https://github.com/apple/swift/pull/39051

будет доступно для macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0

Вы правы! Дополнил в статье этот момент

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


Если у вас проблемы только в этом, то кто мешает везде использовать только асинхронную часть? Ну то есть банально вместо функций возвращающиx void/Т сделать функции возвращающие Task/Task?

Начнем с того, что это невозможно из-за внешних зависимостей. Даже фреймворк годами приводили в нормальный вид. Ну и проблема здесь фундаментальная, а не в том, какие где методы возвращаются. Это невозможно обойти, хоть пусть все методы будут асинхронные. Кооперативная многозадачность как никак. Код постоянно прыгает из синхронной в асинхронную части и в этих местах задействована куча внутренних компонентов фреймворка. Контексты, шедулеры, кодогенерация, вот это все. На этих стыках и возникают все проблемы, которые выше в видео описывают. Дедлоки, гонки, потерянные исключения, исключения, кладущие процесс и т.д. и т.п. Все происходит из-за разделения языка на две половины. Асинки работают просто в примитивных примерах, но в реальности это переусложненный и неочевидный подход к асинхронности. И если в плюса и расте я еще понимаю причины его использовать - stackless корутины таки дешевле для них и это важно, но свифт - он мог спокойно использовать stackful корутины.

Начнем с того, что это невозможно из-за внешних зависимостей.

В большинстве случаев элементарно решается wrapper'ом на стыке с этими самыми зависимостями.


Код постоянно прыгает из синхронной в асинхронную части и в этих местах задействована куча внутренних компонентов фреймворка.

Нет никаких синхронной или асинхронной частей. Есть выполнение в одном или разных потоках или в одном или разных контекстах синхронизации. И это всё вполне себе регулируется. Async/await в шарпах это просто "сахарная обёртка" вокруг ThreadPool. Никакой магии там нет.


И если в плюса и расте я еще понимаю причины его использовать — stackless корутины таки дешевле для них и это важно, но свифт — он мог спокойно использовать stackful корутины.

Я не сообо в курсе как оно там работает в плюса и расте. И отвечал в контексте шарпа.

В большинстве случаев элементарно решается wrapper'ом на стыке с этими самыми зависимостями.

Я надеюсь очевидно, что это плохое решение. Собственно, в этом и проблема. Чтобы код стал асинхронным надо его либо править, либо пытаться обернуть его во что-то, что все равно не сделает его нормальным асинхронным. Как минимум он не будет поддерживать CancellationToken, что чрезвычайно важно. Если он повиснет, то намертво заберет на себя поток. А если есть другие механизмы отмены, то начинается строительство других костылей, чтобы подружить это все. И в этом всем фундаментальная проблема асинков и деления языка на две половины.

Нет никаких синхронной или асинхронной частей

Еще как есть. Пока код выполняется синхронно его невозможно приостановить или как-то на него подействовать без явной реализации этих механизмов. Отсюда и приходят неочевидные дедлоки. Асинки это кооперативная многозадачность и это проблема.

Async/await в шарпах это просто "сахарная обёртка" вокруг ThreadPool.

Это не так. ThreadPool это всего лишь один из вариантов контекстов. Есть еще контексты с главным потоком, где многопоточности нет и можно огрести кучу проблем. Есть контексты asp.net свои хитрые.

Я не сообо в курсе как оно там работает в плюса и расте. И отвечал в контексте шарпа.

Зато я писал глобально о всем механизме, который примерно одинаково работает во всех языках с примерно одинаковыми проблемами, которые присущи stackless корутинам в общем. И мне не нравится, что в языки продолжают ткать этот механизм, когда есть решения лучше.

Я надеюсь очевидно, что это плохое решение.

Нет не очевидно. Как минимум мне.

Чтобы код стал асинхронным надо его либо править, либо пытаться обернуть его во что-то, что все равно не сделает его нормальным асинхронным.

Нет, не надо. Вы просто запускаете его асинхронно в вашем контексте синхронизации и это делает его «нормально асинхронным». При желании можете без контекста, но тут уже надо понимать когда это можно делать.

Да и вообще у вас в любом асинхронном коде будет кусок «обычного» кода, который вы «оборачиваете» в асинхронную оболочку.

Как минимум он не будет поддерживать CancellationToken, что чрезвычайно важно.

Это важно если вам нужен CancellationToken. Или вообще подобный механизм. И если он вам нужен, а у сторонней библиотки он реализован как-то по другому, то это точно так же решется через wrapper. По крайней мере я ни разу не видел варианта чтобы это не решалось. Вы можете привести пример?

Если он повиснет, то намертво заберет на себя поток.

Это решается таймаутами и/или тем же WaitAny(Task[], TimeSpan).

Это не так. ThreadPool это всего лишь один из вариантов контекстов. Есть еще контексты с главным потоком, где многопоточности нет и можно огрести кучу проблем.

Что такое «главный поток» в вашем понимании? И ThreadPool это не вариант контекста. Это механизм работы с потоками на котором сверху пристроен async/await. Уберите ThreadPool и никакого async/await в шарпе у вас не будет.

Зато я писал глобально о всем механизме, который примерно одинаково работает во всех языках с примерно одинаковыми проблемами

Я очень сомневаюсь что он примерно одинаково работает во всех языках. Особенно учитывая что базируется это всё на очень разных вещах.

Похоже что у вас каша в голове в асинхронном программировании. Stackless корутины это круто и скоро захватят мир.

Уже 7 лет использую полную поддержку async/await во всех iOS проектах. Не испытываю проблем ни с обратной совместимостью, ни с производительностью ​

Всё что для этого надо сделать - использовать Xamarin.Native (не путать с Xamarin.Forms).

А если серьезно, то если MS завезли весь свой NetStandart на все версии всех ОС от Apple, то странно, почему Apple ограничивает всё 15й версией.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий