Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/110.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios JSON序列化会冻结UI_Ios_Swift_Kotlin_Kotlin Coroutines_Kotlin Multiplatform - Fatal编程技术网

Ios JSON序列化会冻结UI

Ios JSON序列化会冻结UI,ios,swift,kotlin,kotlin-coroutines,kotlin-multiplatform,Ios,Swift,Kotlin,Kotlin Coroutines,Kotlin Multiplatform,我正在为Android和iOS制作一个Kotlin多平台项目。我的目标是在公共模块中进行联网和JSON序列化,并在目标平台中使用这些数据 但我有一个问题:它会阻塞iOS应用程序上的UI。下载是可以的,因为它是由网络库完成的,但是当JSON足够大并且序列化需要一些时间时,它会冻结UI直到序列化完成 以下是我的步骤: 普通 使用ktor库的请求方法: class NetworkProvider { private val client = HttpClient() suspend f

我正在为Android和iOS制作一个Kotlin多平台项目。我的目标是在公共模块中进行联网和JSON序列化,并在目标平台中使用这些数据

但我有一个问题:它会阻塞iOS应用程序上的UI。下载是可以的,因为它是由网络库完成的,但是当JSON足够大并且序列化需要一些时间时,它会冻结UI直到序列化完成

以下是我的步骤:

普通

使用ktor库的请求方法:

class NetworkProvider {
    private val client = HttpClient()
    suspend fun request(urlString: String): String {
        return client.request<String>(urlString)
    }
}
执行请求:

class Downloader {
    var listener: DownloadListener? = null
    fun download() {
        CustomCoroutineScope().launch {
            val object = request()
            listener?.onCompleted(object)
        }
    }
}
调度程序和协同路由范围:

class UIDispatcher : CoroutineDispatcher() {
    override fun dispatch(context: CoroutineContext, block: Runnable) {
        dispatch_async(dispatch_get_main_queue()) {
            block.run()
        }
    }
}

internal class CustomCoroutineScope : CoroutineScope {
    private val dispatcher = UIDispatcher()
    private val job = Job()
    override val coroutineContext: CoroutineContext
        get() = dispatcher + job
}
iOS

实施
下载侦听器
方法:

func onCompleted(object: CustomObject) {
    // Update the UI
 }
然后打电话请求

downloader.download()
我假设它应该在主线程中异步执行,而不会阻塞UI

我做错了什么?在调用协同程序时,我尝试使用
和context
,但没有任何帮助


有没有办法在公共模块中完成繁重的任务而不阻塞特定平台中的UI?

一旦网络调用完成,Json解析将在主线程上结束。这将阻止主线程上的所有其他内容,包括ui。您需要将Json解析发送到后台线程。下面是一些与kotlin多平台并发的示例


JSON解析是一项繁重的任务,需要在后台线程上完成。不要在主队列上异步调度,而是在全局队列上异步调度。

不要运行此同步。如果需要很长时间,请将其从主线程上移开。使它异步只意味着它不会立即阻塞。嘿@KevinGalligan,我对你的代码有点小麻烦。我的应用程序流与krlb的应用程序流几乎相同,并且您的后台任务解决方案对于解析非常有用。然而,当我经历调用解析周期时,我的HttpClient被冻结,无法再使用,我必须创建另一个,这不是一个可接受的解决方案。经过一番挖掘,我得出了一个结论,这一切都发生了,因为协程延续被传递到
后台任务
,这冻结了协程中的几乎所有内容。你知道如何解决这个问题吗?@JanStoltman协同程序和延续不应该被冻结。它们被保存在主线程中。我看不到您的代码,但我假设您是在后台lambda中捕获HttpClient。小结,如果您有一些示例代码要查看,我可以说得更好。@KevinGalligan您可以在这里找到我代码的重要部分:我使用与Droidcon相同的后台任务。据我所知,我们将继续传递给包装在lambda中的JobWrapper。冻结这个工作包装不会冻结整个续集吗?你知道我的问题吗?
downloader.download()