iOS 上的 KMM:没有事件循环。使用 runBlocking { ... } 开始一个
KMM on iOS: There is no event loop. Use runBlocking { ... } to start one
我正在尝试在 Kotlin Multiplatform
项目中使用 coroutines
。我在这两个方面都没有经验。
我正在尝试调用此函数
fun startFlow {
coroutineScope.launch {
withContext(defaultDispatcher) {
myFlow.collect { next -> onNext(next) }
}
}
}
coroutineScope
iOS
是这个
val defaultScope: CoroutineScope = object : CoroutineScope {
override val coroutineContext: CoroutineContext
get() = SupervisorJob() + Dispatchers.Default
}
这不是给我这个问题的唯一调用,事实上所有对 coroutines
的调用似乎都失败并出现此错误:
kotlin.IllegalStateException: There is no event loop. Use runBlocking { ... } to start one.
这就是我导入库的方式
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3")
}
}
我正在使用 Kotlin
1.4.31。此问题仅存在于 iOS
,Android
完美运行。
我不明白我是否遗漏了什么。
新的本机并发模型 available for preview. Check out New memory model migration guide。此功能与 Kotlin 1.7.0.
一起发布后,将不再需要下面描述的 native-mt
后缀
对于 iOS 您需要使用后缀为“native-mt”的协程,更多信息 here
所以用
替换你的导入
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
另请注意,根据 documentation:
When using other libraries that also depend on kotlinx.coroutines
, such as Ktor, make sure to specify the multithreaded version of kotlinx-coroutines
. You can do this with strictly
:
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt"){
version {
strictly("1.5.2-native-mt")
}
}
您也可以使用常规 coroutines
库,但是您需要创建自定义 CoroutineDispatcher that posts the task on the mainRunLoop,例如:
object NSLooperDispatcher: CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
NSRunLoop.mainRunLoop.performBlock {
block.run()
}
}
}
// use custom dispatcher
withContext(NSLooperDispatcher) {
myFlow.collect { next -> onNext(next) }
}
协程的 native-mt
分支明确指出了切换线程的问题,因此使用它可能仍然是个好主意。否则,您将被限制在一个主线程上。
我正在尝试在 Kotlin Multiplatform
项目中使用 coroutines
。我在这两个方面都没有经验。
我正在尝试调用此函数
fun startFlow {
coroutineScope.launch {
withContext(defaultDispatcher) {
myFlow.collect { next -> onNext(next) }
}
}
}
coroutineScope
iOS
是这个
val defaultScope: CoroutineScope = object : CoroutineScope {
override val coroutineContext: CoroutineContext
get() = SupervisorJob() + Dispatchers.Default
}
这不是给我这个问题的唯一调用,事实上所有对 coroutines
的调用似乎都失败并出现此错误:
kotlin.IllegalStateException: There is no event loop. Use runBlocking { ... } to start one.
这就是我导入库的方式
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3")
}
}
我正在使用 Kotlin
1.4.31。此问题仅存在于 iOS
,Android
完美运行。
我不明白我是否遗漏了什么。
新的本机并发模型 available for preview. Check out New memory model migration guide。此功能与 Kotlin 1.7.0.
一起发布后,将不再需要下面描述的native-mt
后缀
对于 iOS 您需要使用后缀为“native-mt”的协程,更多信息 here
所以用
替换你的导入implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
另请注意,根据 documentation:
When using other libraries that also depend on
kotlinx.coroutines
, such as Ktor, make sure to specify the multithreaded version ofkotlinx-coroutines
. You can do this withstrictly
:
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt"){
version {
strictly("1.5.2-native-mt")
}
}
您也可以使用常规 coroutines
库,但是您需要创建自定义 CoroutineDispatcher that posts the task on the mainRunLoop,例如:
object NSLooperDispatcher: CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
NSRunLoop.mainRunLoop.performBlock {
block.run()
}
}
}
// use custom dispatcher
withContext(NSLooperDispatcher) {
myFlow.collect { next -> onNext(next) }
}
协程的 native-mt
分支明确指出了切换线程的问题,因此使用它可能仍然是个好主意。否则,您将被限制在一个主线程上。