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
相关产品推荐
相关产品推荐

