为什么延迟块在同一函数中的闭包完成之前执行

Why is defer block executed before a closure finishes in the same function

我编写了以下函数来添加地图注释,该注释使用 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)")
        }
    })
}

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

您的 defer 块中的代码无法移入您的完成处理程序是否有原因?

你误解了延迟块的作用。

这是一段代码,在您退出当前范围时执行。

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

然后您的方法结束并且执行超出了方法的范围。延迟块被执行。稍后,异步方法完成其后台工作并调用您传递给它的完成处理程序。使用将 ALWAYS 发生在调用方法 returns.

之后的异步方法

@fqdn 的想法是对的。将您的清理代码放在完成块中。这就是它所属的地方。