iOS 上的 KMM:没有事件循环。使用 runBlocking ... 启动一个
Posted
技术标签:
【中文标题】iOS 上的 KMM:没有事件循环。使用 runBlocking ... 启动一个【英文标题】:KMM on iOS: There is no event loop. Use runBlocking ... to start oneiOS 上的 KMM:没有事件循环。使用 runBlocking ... 启动一个 【发布时间】:2021-06-29 05:19:39 【问题描述】:我正在尝试在 Kotlin Multiplatform
项目中使用 coroutines
。我都没有这方面的经验。
我正在尝试调用这个函数
fun startFlow
coroutineScope.launch
withContext(defaultDispatcher)
myFlow.collect next -> onNext(next)
coroutineScope
on 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
完美运行。
我不明白我是否遗漏了什么。
【问题讨论】:
【参考方案1】:对于 iOS,您需要使用后缀为“native-mt”的协程,更多信息here
所以用
替换你的导入implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
另请注意,根据documentation:
当使用也依赖于
kotlinx.coroutines
的其他库时,例如Ktor,请确保指定kotlinx-coroutines
的多线程版本。你可以通过strictly
做到这一点:
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
version
strictly("1.5.2-native-mt")
附言新的原生并发模型available 用于预览。查看New memory model migration guide。在此功能发布后,将不再需要 native-mt
后缀。
【讨论】:
在协同程序的 GitHub 存储库上,它说如果您对公共源集具有通用依赖项,它将导入特定于平台的版本。我虽然不需要后缀 我已经用官方文档替换了一个链接,它描述了为什么我们仍然需要使用它。不久 - 他们仍在努力。此外,您还可以找到如何严格使用版本,以防您的其他依赖项依赖于协程 未捕获的 Kotlin 异常:kotlin.native.IncorrectDereferenceException:非法尝试从其他线程访问非共享 @BoldijarPaul 这是另一个问题。查看 Kotlin Native 并发模型在 documentation 中的工作原理。很快,您就不能在共享代码中使用var
(没有原子包装器),但是当您需要在创建新对象时调用froze
时也会遇到问题。您问题中的代码似乎不会导致此类异常。您可以使用更多详细信息/堆栈跟踪以及相关代码更新您的问题,以防您在文档中找不到答案。【参考方案2】:
您也可以使用常规的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
分支明确指出切换线程存在问题,因此使用它可能仍然是一个好主意。否则,您将被限制在一个主线程上。
【讨论】:
以上是关于iOS 上的 KMM:没有事件循环。使用 runBlocking ... 启动一个的主要内容,如果未能解决你的问题,请参考以下文章
无法将 io.ktor 导入 Android Studio 中 KMM 的通用模块
Kotlin Multiplatform (KMM) 中的对象在 Swift 函数中实例化。函数结束它的作用域。谁释放了对象?