Задержка сопрограмм Kotlin не работает в диспетчере очереди iOS
У меня есть приложение KMM, и есть код:
fun getWeather(callback: (WeatherInfo) -> Unit) {
println("Start loading")
GlobalScope.launch(ApplicationDispatcher) {
while (true) {
val response = httpClient.get<String>(API_URL) {
url.parameters.apply {
set("q", "Moscow")
set("units", "metric")
set("appid", weatherApiKey())
}
println(url.build())
}
val result = Json {
ignoreUnknownKeys = true
}.decodeFromString<WeatherApiResponse>(response).main
callback(result)
// because ApplicationDispatcher on IOS do not support delay
withContext(Dispatchers.Default) { delay(DELAY_TIME) }
}
}
}
И если я заменю
withContext(Dispatchers.Default) { delay(DELAY_TIME) }
с участием
delay(DELAY_TIME)
выполнение никогда не возвращается в цикл while, и у него будет только одна итерация.
А для IOS выглядит так:
internal actual val ApplicationDispatcher: CoroutineDispatcher = NsQueueDispatcher(dispatch_get_main_queue())
internal class NsQueueDispatcher(
private val dispatchQueue: dispatch_queue_t
) : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatch_async(dispatchQueue) {
block.run()
}
}
}
И из
delay
исходный код, я могу догадаться, что
DefaultDelay
должен быть возвращен, и должно быть аналогичное поведение с / без
withContext(Dispatchers.Default)
/** Returns [Delay] implementation of the given context */
internal val CoroutineContext.delay: Delay get() = get(ContinuationInterceptor) as? Delay ?: DefaultDelay
Спасибо!
PS у меня есть
ApplicationDispatcher
из ктор-образцов .
1 ответ
Наверное
ApplicationDispatcher
это что-то старое, вам больше не нужно его использовать:
CoroutineScope(Dispatchers.Default).launch {
}
или же
MainScope().launch {
}
И не забывайте использовать
-native-mt
версия сопрограмм, подробнее в этом выпуске