You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift串行DispatchQueue未串行执行问题求助

问题描述

我的代码中sendRequest函数会被多次调用,该函数负责向服务器发送请求,服务器会逐个处理请求并返回多个响应。我希望handleResponse函数在串行队列中处理这些响应,同一时间仅执行一次,但日志显示handleResponse还没执行完就被多次调用了。简化后的代码如下:

func sendRequest() { // 被多次调用
    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")

    // 执行一些操作并将响应数据写入本地存储

    DispatchQueue.main.async {
        // 更新UI
    }

    Logger.d("end handleResponse")
}

请问如何让回调按串行方式工作?


解决方案

问题核心是你每次进入successHandler时都会创建新的串行队列,这些队列相互独立,各自的任务会并行执行,根本起不到串行控制的作用。

只需要把串行队列改为类的成员属性,确保所有回调任务都提交到同一个串行队列即可:

// 在类内部定义全局的串行队列,而非在回调里临时创建
private let serialResponseQueue = DispatchQueue(label: "serialResponseQueue", qos: .background)

func sendRequest() { // 被多次调用
    applicationNetworkManager().sendQuery(
        ...
        successHandler: { [weak self] response in
            guard let self = self else { return }
            
            self.serialResponseQueue.async {
                self.handleResponse(response: response)
            }
        }
    )
}

func handleResponse(response: Response) {
    Logger.d("start handleResponse")

    // 执行一些操作并将响应数据写入本地存储

    DispatchQueue.main.async {
        // 更新UI
    }

    Logger.d("end handleResponse")
}

额外说明:

  • 用[weak self]配合guard let解包,比直接使用self!更安全,避免循环引用风险
  • 同一个串行队列会严格按任务添加顺序执行,前一个任务执行完毕后才会启动下一个,确保handleResponse同一时间仅执行一次

内容的提问来源于stack exchange,提问作者Takrem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 04:58:14