2015-10-04 57 views
-4

我在Swift 2.0中編寫了以下函數來添加一個使用CLGeocoder()來解析給定座標的位置名稱的地圖註釋。我使用defer塊來獲得解析的位置名稱,但是,延遲塊似乎在閉合完成之前完成。下面是我的代碼:Swift 2:在閉包在相同函數中完成之前執行了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)") 
       } 
      }) 

} 
+0

這是正確和正確的行爲。你忘了問一個問題。 –

回答

3

reverseGeocodeLocation(_:completionHandler:)異步執行,這是有道理的,在你的defer塊中的代碼爲completionHandler參數調用

通過關閉前執行是有原因的代碼您的defer塊無法移入您的完成處理程序中?

3

你誤解了推遲塊的功能。

這是一個代碼塊,當您退出當前範圍時會執行該代碼塊。

當您使用完成塊執行異步方法時,它立即返回並執行到下一行。被調用的方法將獲取完成塊並將其保存以備後用。

然後您的方法結束並執行超出方法的範圍。推遲塊被執行。在稍後的時間,異步方法完成後臺工作並調用您傳遞給它的完成處理程序。在調用方法返回後發生異步方法,將會發生ALWAYS

@fqdn有正確的想法。把你的清理代碼放在完成塊中。這就是它所屬的地方。

相關問題