Swift中调用带闭包的异步函数的同步函数无法获取返回值问题问询
核心矛盾
异步执行逻辑无法直接给同步函数返回结果:checkUserSomething 内部的 Client.get() 是异步网络请求,不会阻塞当前线程,isUserHome 执行到返回语句时网络请求还没拿到结果,自然获取不到预期返回值。
解决方案
如果必须保留 isUserHome() -> Bool 的签名不做修改,可通过 DispatchSemaphore 把异步操作转为同步阻塞,实现代码如下:
func isUserHome() -> Bool { let semaphore = DispatchSemaphore(value: 0) var result = false checkUserSomething { success in result = success semaphore.signal() } // 等待异步回调执行完成,可根据业务需要设置超时时间避免永久卡死 semaphore.wait() return result } // 原checkUserSomething无需修改,如需兼容异常场景可补充错误分支处理 func checkUserSomething(completion: @escaping (_ success: Bool) -> Void) { Client.get() { (response) in completion(response.isHome) } }
注意事项
- 该方案会阻塞调用
isUserHome的线程,禁止在主线程调用此方法,否则会导致UI无响应,甚至被系统 watchdog 直接杀掉 - 请确保
checkUserSomething的completion在所有分支(包括请求失败、超时等异常场景)都会被调用,否则会触发线程永久卡死 - 从iOS开发规范来看,异步网络请求对应的上层方法应该设计为异步回调或者
async签名,上述方案仅为满足强制同步返回的临时兼容方案,长期来看还是建议调整上层依赖的调用逻辑更稳妥
内容的提问来源于stack exchange,提问作者lavta3
相关产品推荐
相关产品推荐

