为什么在同一个函数的闭包完成之前执行defer块?



我编写了以下函数来添加一个地图注释,该注释使用CLGeocoder()来解析给定坐标的位置名称。我使用defer块来获得解析的位置名称。然而,defer块似乎在关闭完成之前就完成了。为什么?

下面是我的代码:
func addAnnotation(gestureRecognizer: UIGestureRecognizer) {
    var locationNameStr = ""
    defer {
        let newPin = Pin(dictionary: locationDictionary, context: sharedContext)
        newPin.name = locationNameStr
        do {
            //persist the new pin to core data
            try sharedContext.save()
            showPinOnMap(newPin)
        } catch let error as NSError {
            print("error saving the new pin in context")
        }
    }
    // use CLGeocoder to resolve the location name as title of the annotation
    CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: newCoordinate.latitude, longitude: newCoordinate.longitude), completionHandler: {(placemarks, error) -> Void in
        if error != nil {
            print("reverse geocoding failed with error: (error)")
            //return
        } else if placemarks!.count > 0 {
            let firstPlace = placemarks![0] as CLPlacemark
            if firstPlace.country != nil {
                locationNameStr = "a place in (firstPlace.country!)"
            }
            else if firstPlace.locality != nil {
                locationNameStr = "a place in (firstPlace.locality!)"
            }
            print("location name: (locationNameStr)")
        }
    })
}

你误解了defer block的作用。

退出当前作用域时执行的代码块。

当你执行带有完成块的异步方法时,它会立即返回并继续执行到下一行。被调用的方法获取你的完成块,并将其保存以供以后使用。

然后你的方法结束并且执行超出了方法的作用域。执行defer块。稍后,异步方法完成后台工作并调用传递给它的完成处理程序。使用一个async方法,在调用方法返回后ALWAYS发生。

@fqdn的想法是对的。将清理代码放在完成块中。

reverseGeocodeLocation(_:completionHandler:)异步执行,defer块中的代码在调用completionHandler参数传递的闭包之前执行是有意义的

有一个原因,在你的defer块的代码不能移动到你的完成处理程序?

最新更新