嘿,在我的代码中,函数“sendRequest”被多次调用,它向服务器发送请求。服务器一个接一个地处理所有请求并发回多个响应。现在我想在函数“handleResponse”中处理这些响应,但在串行队列中。所以 handleResponse 只会同时被调用一次。但是现在我的日志看起来像这样:
[15.05.2023 11:28:00.711] DEBUG NetworkDataHandler:52 - start handleResponse
[15.05.2023 11:28:00.710] DEBUG NetworkDataHandler:52 - start handleResponse
[15.05.2023 11:28:00.713] DEBUG NetworkDataHandler:52 - start handleResponse
[15.05.2023 11:28:00.713] DEBUG NetworkDataHandler:52 - start handleResponse
[15.05.2023 11:28:00.714] DEBUG NetworkDataHandler:52 - start handleResponse
...
handleResponse 因此被多次调用,尽管它还没有完成。我怎样才能让回调连续工作?
简化代码:
func sendRequest() { // is called several times
applicationNetworkManager().sendQuery(
...
successHandler: { response in
let workItem = DispatchWorkItem {
self!.handleResponse(response: response)
}
let serialQueue = DispatchQueue(label: "serialQueue", qos: .background)
serialQueue.async(execute: workItem)
}
)
}
func handleResponse(response: Response) {
Logger.d("start handleResponse")
// do some stuff and write response data to local storage
DispatchQueue.main.async {
// update ui
}
Logger.d("end handleResponse")
}
在
sendRequest
中,您每次调用let serialQueue = DispatchQueue(label: "serialQueue", qos: .background)
时都会创建一个新的调度队列。尽管所有队列实例都具有相同的标签,但它们是不同的队列。
你没有展示你是如何创建包含
sendRequest
的类的,所以我不确定这个类是否有一个实例或者你是否有多个实例。
也最好避免
.background
QoS;在低功耗情况下,此 QoS 级别可能会导致 CPU 饥饿。 .utility
是个不错的选择
假设你有一个实例,你会使用类似的东西:
class NetworkHandler {
let myQueue: DispatchQueue
init() {
self.myQueue = DispatchQueue(label:"serialQueue", qos: .utility, target: .global(qos:.utility))
}
}
然后您可以在处理程序中使用此队列。
请注意,将您的队列定位到全局队列之一以最小化线程创建是个好主意。