首页 > 解决方案 > 在与 iOS 中的调用者相同的线程上运行回调

问题描述

我从 Kotlin/Native 框架调用原生 iOS 端的一个方法。该方法以异步方式完成其工作,并在与调用它的线程不同的线程中返回一些数据。

我想要一种在同一个线程中调用响应函数的方法。下面是代码:

func makePostRestRequest(url: String, body: String) { 

    let thread1 = Thread.current

    let request = NetworkServiceRequest(url: url,
                                        httpMethod: "POST",
                                        bodyJSON: body)
    NetworkService.processRequest(requestModel: request) { [weak self] (response: Any?, requestStatus: RequestStatus) in
        // This is different thread than "thread1". Need the below code to execute on "thread1"
        if requestStatus.result == .fail {
            knResponseCallback.onError(errorResponse: requestStatus.error)
        } else {
            knResponseCallback.onSuccess(response: response)
        }
    }
}

我试图用两种方法解决这个问题。

一种是使用“信号量”。我只是在网络调用之后阻止了代码执行,当我在网络请求的回调中得到结果时,我将它保存在一个变量中并发出信号量。之后,我只需调用 knResponseCallback 并使用 response 变量返回响应。

我使用的另一种方法是使用 RunLoops。我得到了 RunLoop.current 的句柄,以一种模式启动 runLoop,在网络请求的回调中,我只是调用perform selector on thread with objectNSObject 的方法,它将工作分派给该线程本身。

他们两个的问题是他们正在阻止呼叫。RunLoop.run 和 semaphore.wait 都阻塞了调用它们的线程。

有没有办法在不阻塞特定线程的情况下将一些工作从另一个线程分派到特定线程?

标签: iosswiftnsthreadkotlin-nativerunloop

解决方案


您需要创建一个队列来发送请求并使用同一个队列来处理响应。像这样的东西应该适合你:

    let queue = DispatchQueue(label: "my-thread")
        queue.async {
            let request = NetworkServiceRequest(url: url,
                                                httpMethod: "POST",
                                                bodyJSON: body)
            NetworkService.processRequest(requestModel: request) { [weak self] (response: Any?, requestStatus: RequestStatus) in
                queue.async {
                    if requestStatus.result == .fail {
                        knResponseCallback.onError(errorResponse: requestStatus.error)
                    } else {
                        knResponseCallback.onSuccess(response: response)
                    }
                }
            }
        }

推荐阅读