Swift 5为函数添加completionHandler报逃逸闭包捕获错误如何解决
问题原因
- Swift默认函数的闭包参数为*非逃逸(nonescaping)*类型,仅允许在函数当前执行周期内、函数体内部直接调用,不允许被内部的异步逃逸闭包捕获、延后到函数返回后执行
- 你代码中用到的
.done、.catch都是异步回调的逃逸闭包,会在网络请求结束后才执行,此时getValueFromAPI函数早已返回,捕获非逃逸的completionHandler就会触发报错 - 隐藏问题:你当前仅在请求成功的分支调用了
completionHandler,请求失败的两个catch分支都没有调用,会导致调用方在请求失败时永远收不到回调
修复方案
- 给
completionHandler参数添加@escaping修饰符,声明该闭包允许逃逸出函数体 - 在两个
catch分支也补全completionHandler的调用,传入false表示操作失败
修改后的完整代码:
func getValueFromAPI(completionHandler: @escaping (_ result: Bool) -> Void){ apii.getVehicle(id!).done { (vehicle: Vehicle) -> Void in print("ggg.state: \(vehicle.state!)") print("ggg.state: \(vehicle.displayName!)") apii.getAllData(vehicle).done { (extendedVehicle: VehicleExtended) in let entryBattery = (extendedVehicle.chargeState?.batteryLevel)! let entryCarState = (extendedVehicle.state)! print("entryBattery: \(entryBattery)") print("entryCarState: \(entryCarState)") completionHandler(true) }.catch { (error) in print("ERROOOOR: \(error)") completionHandler(false) } }.catch { error in print("errorr: \(error)") completionHandler(false) } }
内容的提问来源于stack exchange,提问作者Erik Auranaune
相关产品推荐
相关产品推荐

