kotlin.native.concurrent.InvalidMutabilityException:在 Kotlin Multiplatform 中使用 ktor 时冻结 <object> 的变异尝试 (iOS)
kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen <object> when using ktor in Kotlin Multiplatform (iOS)
我正在尝试构建一个简单的 Kotlin 多平台应用程序,它调用互联网以使用 ktor 从互联网上获取一些字符串。我从 Kotlin conference app 中提取了一些我编译的函数,它在 Android 和 iOS 上都运行良好。
但是,在我的示例应用程序中,它仅适用于 Android,但适用于 iOS returns
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()
}
}
原来是 Kotlin 版本 1.3.11
导致了问题。我已将其降级为 1.3.10
,并且运行良好。 ktor 将在下一个次要版本中得到修复。
来源 - Kotlin Slack,多平台频道。
我正在尝试构建一个简单的 Kotlin 多平台应用程序,它调用互联网以使用 ktor 从互联网上获取一些字符串。我从 Kotlin conference app 中提取了一些我编译的函数,它在 Android 和 iOS 上都运行良好。
但是,在我的示例应用程序中,它仅适用于 Android,但适用于 iOS returns
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()
}
}
原来是 Kotlin 版本 1.3.11
导致了问题。我已将其降级为 1.3.10
,并且运行良好。 ktor 将在下一个次要版本中得到修复。
来源 - Kotlin Slack,多平台频道。