kotlin.native.concurrent.InvalidMutabilityException:在Kotlin Multiplatform(iOS)中使用ktor时,冻结的<object>的突变尝试

时间:2018-12-13 04:56:01

标签: ios kotlin ktor kotlin-native kotlin-multiplatform

我正在尝试构建一个简单的Kotlin Multiplatform应用程序,该应用程序可以调用互联网以使用ktor从互联网获取一些字符串。我从Kotlin conference app中提取了一些函数,这些函数是我编译的,并且在Android和iOS上都能正常工作。

但是,在我的示例应用中,它仅适用于Android,但在iOS上会返回

kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen <object>@c422ffe8

这是GitHub repository,下面是我的代码:

// src/commonMain/CoroutinePresenter.kt

open class CoroutinePresenter(
    private val mainContext: CoroutineContext, // TODO: Use Dispatchers.Main instead when it will be supported on iOS
    private val baseView: BaseView
): CoroutineScope {

    private val job = Job()
    private val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
        baseView.showError(throwable)
    }

    override val coroutineContext: CoroutineContext
        get() = mainContext + job + exceptionHandler

    open fun onDestroy() {
        job.cancel()
    }
}

-

// src/commonMain/SamplePresenter.kt

class SamplePresenter(
    val uiContext: CoroutineContext,
    baseView: BaseView,
    val sampleView: SampleView
) : CoroutinePresenter(uiContext, baseView) {
    private val client = HttpClient()

    fun callSimpleApi() {
        try {
            GlobalScope.launch(uiContext) {
                getToolString()
            }
        } catch (e: Exception) {
            sampleView.returnString(e.toString())
        }
    }

    suspend fun getToolString() = client.get<String> {
        url("https://tools.ietf.org/rfc/rfc1866.txt")
    }

    override fun onDestroy() {
        super.onDestroy()
    }
}

-

// src/iosMain/SampleIos.kt
object MainLoopDispatcher: CoroutineDispatcher() {
    override fun dispatch(context: CoroutineContext, block: Runnable) {
        NSRunLoop.mainRunLoop().performBlock {
            block.run()
        }
    }
}

-

// iosApp/iosApp/ViewController.swift
import app

class ViewController: UIViewController, SampleView, BaseView {
    private lazy var presenter: SamplePresenter = { SamplePresenter(
        uiContext: MainLoopDispatcher(),
        baseView: self,
        sampleView: self
        )
    }()
    @IBOutlet weak var label: UILabel!

    func showError(error: KotlinThrowable) {
        print(error.message)
    }

    func returnString(result: String) {
        label.text = result
        print(result)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        print("helo")
        presenter.callSimpleApi()
    }
}

1 个答案:

答案 0 :(得分:4)

事实证明,Kotlin版本var sp = ["48343", "48383", "48934893", "438943", "47849345", "45843945", "47483923", "38445"]; for (var i = 0; i < sp.length; i += 1) { check(sp[i]); } 引起了麻烦。我已将其降级为1.3.11,并且效果很好。 ktor将在下一个次要版本中获得修复。

来源-Kotlin Slack,多平台渠道。