Kotlin Multiplatform:IllegalStateException:必须是主线程

Kotlin Multiplatform: IllegalStateException: Must be main thread

我正在使用 Koin 3.0.0-alpha-4 版本,当我尝试使用 koin 注入的 class 时,它会为 iOS 端抛出异常: KotlinException=kotlin.IllegalStateException: Must be main thread, KotlinExceptionOrigin 我有一个单身人士 class ,我正在使用 koin 初始化对象:

@ThreadLocal
object ObjectFactory : KoinComponent{
  val appStateRepository: AppStateRepository by inject()
  val appStateRepositoryDemo =  AppStateRepository()
}

如果我在由 koin 注入的后台线程 (Dispatchers.Default) 中使用 appStateRepository,那么它会抛出异常 IllegalStateException: Must be main thread,但是如果我使用 appStateRepositoryDe​​mo 则它工作正常

这是我从 iOS 调用的注入模块的方法

fun initKoinIos(
  userDefaults: NSUserDefaults,
  doOnStartup: () -> Unit
): KoinApplication = initKoin {
  module {
    ...
    single { doOnStartup }
  }
}
fun initKoin(appDeclaration: KoinAppDeclaration = {}) = startKoin {
  appDeclaration()
  modules(
    platformModule,
    networkModule,
    useCaseModules,
    repositoryModule,
    commonUtils,
  )
}

用法如下:

fun testRepoAccess() {
     ObjFactory.appStateRepository.test() // Ok, here we are in main thread

     CoroutineScope(Dispatchers.Default).launch {
       ObjFactory.appStateRepositoryDemo.test() //  Ok
       ObjFactory.appStateRepository.test() // Not Ok, throws exception (Must be main thread)
     }
}

预期行为 它应该适用于 iOS 就像它适用于 Android

Koin 3.0.0-alpha-4

附加模块定义

Coroutines 1.4.2-native-mt

更新

我使用了错误的 Koin 库名称,现在我使用:

io.insert-koin:koin-core:3.0.1

现在我有另一个例外:

  kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared org.koin.core.context.GlobalContext.KoinInstanceHolder@1c02ca8 from other thread

Kotlin/Native 上的 Koin 需要在主线程上注入,以避免冻结 Koin 状态。因此,您实际上无法直接从后台线程注入。

添加一个特殊的注入方法,允许您通过切换到主线程来注入,本来打算添加到 Koin 中,但我很确定它永远不会在代码中结束。主要是因为很少有人需要它。

所以,无论如何,您不能用 Koin 做到这一点。您可以尝试 Kodein,但我编写 Koin 的实现恰恰是为了抛出,因为从另一个线程触摸 Koin 会冻结其中的所有内容,而这可能不是您想要做的。

我知道没有人喜欢没有答案,但为什么 ObjectFactory @ThreadLocal?我假设让它保持可变,但如果 appStateRepository 是单个的,它无论如何都会被冻结。