问题描述
我正在尝试在 coroutines
项目中使用 Kotlin Multiplatform
。我在这方面都没有经验。
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
可以完美运行。
我不明白我是否遗漏了什么。
解决方法
对于 iOS,您需要使用后缀为“native-mt”的协程,更多信息 here
所以用
替换你的导入implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3-native-mt")
,
您也可以使用常规的 coroutines
库,但是您需要创建一个自定义的 CoroutineDispatcher,将任务发布到 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
分支明确指出的切换线程存在问题,因此使用它可能仍然是一个好主意。否则,您将被限制在一个主线程上。