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

我的completion block为何失效?Alamofire同步请求未达预期

问题分析

从你给出的输出顺序 leaving viewDidLoad leaving loadData loading successfull 来看,你的请求实际上还是异步执行的——completion block并没有等待请求完成就继续往下走了,导致viewDidLoad和loadData都执行完毕后,请求的回调才触发。

这大概率是因为你实现"同步请求"的方式存在问题,比如没有正确使用信号量(Semaphore)或者调度组(DispatchGroup)来阻塞线程等待请求完成。

正确的Alamofire同步请求实现方式

要让Alamofire请求真正同步执行,你可以用DispatchSemaphore来阻塞当前线程,直到请求完成。但要注意:绝对不能在主线程调用阻塞操作,否则会导致UI卡死甚至死锁!

步骤1:封装同步请求的loadData方法

func loadData(completion: @escaping () -> Void) {
    // 创建信号量,初始值为0
    let semaphore = DispatchSemaphore(value: 0)
    
    AF.request("你的接口URL").responseJSON { response in
        defer {
            // 请求完成后发送信号,唤醒等待的线程
            semaphore.signal()
        }
        
        switch response.result {
        case .success(let value):
            print("loading successful")
            // 处理返回的数据
            // ...
            completion()
        case .failure(let error):
            print("请求失败: \(error.localizedDescription)")
            completion()
        }
    }
    
    // 阻塞当前线程,直到收到信号
    semaphore.wait()
}

步骤2:在后台线程调用同步请求

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 把同步请求放到后台线程执行,避免阻塞主线程
    DispatchQueue.global(qos: .userInitiated).async {
        self.loadData {
            // 如果需要更新UI,必须切回主线程
            DispatchQueue.main.async {
                self.tableView.reloadData()
                // 其他UI操作
            }
        }
        print("leaving loadData")
    }
    
    print("leaving viewDidLoad")
}

预期输出顺序

这样调整后,输出顺序会变成:
leaving viewDidLoad loading successful leaving loadData

(因为viewDidLoad会先执行到print,然后后台线程开始处理请求,请求完成后打印loading successful,最后打印leaving loadData)

常见错误点排查
  1. 在主线程调用semaphore.wait():Alamofire的默认回调队列是主线程,如果你在主线程阻塞,回调永远无法执行,导致死锁。
  2. 信号量使用错误:比如忘记调用signal(),或者调用时机不对(比如在completion之后才signal)。
  3. 混淆同步请求和completion顺序:即使是同步请求,如果你把loadData放到后台线程,viewDidLoad的print还是会先执行,这是正常的——因为后台线程的执行不会阻塞主线程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:28:44