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

Swift技术问题:Completion Closure从未执行,求错误排查

问题:Swift中Completion Closure始终无法执行怎么办?

我尝试获取foobar函数返回的字符串,最初直接返回字符串时Swift会提前/异步返回。当前代码中调用foobar时,其Completion Closure始终无法执行,相关代码如下:

@IBAction func bAction(_ sender: UIButton) {
    print("this prints")
    foobar(completion: { (info) in
        print("this does not print")
    })
}

func foobar(completion: @escaping (_ info: String) -> ()) {
    var info = ""
    //insert code here
    print("this prints too")
    //insert more code here
}

请问我哪里出错了?


回答

嗨,这个问题其实挺常见的——你定义了带逃逸闭包的foobar函数,但自始至终都没有主动调用这个闭包啊!

闭包就像你提前打包好的一段任务逻辑,你得手动触发它,它才会执行。你现在只把闭包当成参数传给了foobar,但函数内部完全没去调用它,那它当然不会自己跑起来。

你需要在foobar函数里,当你准备好要传递的info内容之后,调用completion(info),比如:

func foobar(completion: @escaping (_ info: String) -> ()) {
    var info = ""
    // 这里写你的业务逻辑,给info赋值
    info = "你最终要传递的字符串内容"
    print("this prints too")
    // 调用闭包,把结果传递出去
    completion(info)
}

这样当foobar执行到completion(info)这一行时,你在bAction里传入的闭包就会被触发,print("this does not print")也就会正常输出了。

另外补充个小细节:如果你的foobar里有异步操作(比如网络请求、本地文件读写),记得要在异步任务完成的回调里调用completion,不然还是会出现逻辑提前执行的问题。举个网络请求的例子:

func foobar(completion: @escaping (_ info: String) -> ()) {
    var info = ""
    // 模拟异步网络请求
    URLSession.shared.dataTask(with: yourTargetURL) { data, response, error in
        // 处理返回数据,给info赋值
        if let data = data, let resultStr = String(data: data, encoding: .utf8) {
            info = resultStr
        }
        // 如果需要更新UI,记得切回主线程
        DispatchQueue.main.async {
            completion(info)
        }
    }.resume()
    print("this prints too")
}

这样就能保证闭包在异步任务真正完成后才被调用,逻辑就正常啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:34:29