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

在DispatchQueue.main.async中调用函数的Swift代码技术咨询

问题分析与修复方案

从你的代码来看,你想要利用DispatchGroup等待所有uploadPhoto任务完成后输出"done",但当前的写法存在两个关键问题:

  1. DispatchGroup的enter()/leave()不匹配:你只调用了一次group.enter(),但循环里会触发多个uploadPhoto任务,每个异步任务都需要单独的enter()来标记任务开始。
  2. leave()调用时机错误:你在主队列的循环结束后立刻调用group.leave(),但uploadPhoto里的网络请求是异步执行的——这意味着leave()会在所有上传任务完成前就被调用,导致group.notify提前触发,无法正确等待所有任务结束。

修复后的代码示例

首先调整DispatchGroup的使用逻辑,确保每个异步上传任务都对应一对enter()/leave():

let group = DispatchGroup()

// 主队列是串行队列,循环可以直接执行,无需额外async包裹(如果循环耗时可移到后台队列)
for i in 0 ... (Global.selectedIcons.count - 1) {
    group.enter() // 每个上传任务开始前标记enter
    
    if self.albumorphoto == 1 {
        self.detector = i == 0 ? 1 : 2
    } else {
        self.detector = 0 // 可根据实际需求设置默认值
    }
    
    self.uploadPhoto {
        // 在上传任务的异步回调里标记leave
        group.leave()
    }
}

group.notify(queue: .main) {
    print("done")
}

// 改造uploadPhoto函数,添加完成回调
func uploadPhoto(completion: @escaping () -> Void) {
    guard let url = URL(string: "你的上传地址") else {
        completion()
        return
    }
    var request = URLRequest(url: url)
    // 配置request(比如设置HTTPMethod、请求体、Header等)
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        // 处理上传结果
        defer {
            // 无论成功失败,都调用completion触发leave,保证Group计数正确
            completion()
        }
        
        if let error = error {
            print("上传失败: \(error.localizedDescription)")
            return
        }
        
        // 处理上传成功后的逻辑(比如解析响应数据)
        print("第\(self.detector)类资源上传成功")
    }
    task.resume()
}

额外说明

  • 如果你的uploadPhoto原本没有完成回调,必须添加一个闭参来通知外部任务完成——这是确保DispatchGroup能正确跟踪异步任务的核心。
  • 如果循环本身耗时(比如需要处理大量本地图片压缩),建议把循环放到后台队列执行,避免阻塞主队列影响UI响应:
    DispatchQueue.global().async {
        let group = DispatchGroup()
        // 循环逻辑...
        
        group.notify(queue: .main) {
            print("done")
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:07:00