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

Ton*_*yGW -3 asynchronous ios deferred clgeocoder swift

我在Swift 2.0中编写了以下函数来添加一个地图注释,用于CLGeocoder()解析给定坐标的位置名称.我使用一个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)")
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

Dun*_*n C 6

你误解了延迟块的作用.

它是退出当前范围时执行的代码块.

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

然后,您的方法完成并执行传递出方法的范围.延迟块被执行.稍后,异步方法完成它的后台工作并调用传递给它的完成处理程序.使用异步方法,在调用方法返回后总是会发生.

@fqdn有正确的想法.将清理代码放在完成块中.这就是它所属的地方.


fqd*_*qdn 5

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

有没有理由defer不能将块中的代码移入完成处理程序?