为什么延迟块在同一函数中的闭包完成之前执行
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 的想法是对的。将您的清理代码放在完成块中。这就是它所属的地方。
我编写了以下函数来添加地图注释,该注释使用 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 的想法是对的。将您的清理代码放在完成块中。这就是它所属的地方。