Swift中CLLocationManager模拟场景下Completion Handler未回调问题
问题根因
getCurrentLocation方法的执行顺序存在逻辑错误:你先调用了self.locationManager.requestLocation(),再给self.currentLocationCallback赋值。对于你的Mock实现来说,requestLocation()被调用时会立刻同步触发didUpdateLocations代理方法,这时候currentLocationCallback还没完成赋值,代理中执行回调时自然没有可调用的闭包,等代理逻辑走完你才把回调存到类变量里,当然不会触发外层的completion。
修复方案
只需要调换两个语句的执行顺序,先存储回调,再发起位置请求即可,同时兼容测试和生产环境的执行逻辑:
func getCurrentLocation(completion: @escaping (CLLocation) -> Void) { // 先存储回调,再发起位置请求 self.currentLocationCallback = { (location) in completion(location) } self.locationManager.requestLocation() }
生产环境下系统原生CLLocationManager的requestLocation触发代理是异步行为,所以原顺序问题不会暴露,但测试场景下Mock的同步触发逻辑刚好暴露了这个隐含的顺序缺陷,修正后两边场景都可以正常运行。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

