how to return value after the execution of the block? Swift

对着背影说爱祢 提交于 2019-12-29 09:14:10

问题


I want to get a value from function. There is a block in function. When block executes the function already returns the value. I tried many different methods but they didn't help me. I used NSOperation and Dispatch. The function always returns value until execution of block.

   var superPlace: MKPlacemark!

 func returnPlaceMarkInfo(coordinate: CLLocationCoordinate2D) -> MKPlacemark? {
    let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
    geocoder.reverseGeocodeLocation(location) { (arrayPlaceMark, error) -> Void in
            if error == nil {
                let firstPlace = arrayPlaceMark!.first!
                let addressDictionaryPass = firstPlace.addressDictionary as! [String : AnyObject]

                self.superPlace = MKPlacemark(coordinate: location.coordinate, addressDictionary: addressDictionaryPass)
            }
        }

    return superPlace
}

回答1:


You cannot simply return here as the reverseGeocodeLocation function is running asynchronously so you will need to use your own completion block:

var superPlace: MKPlacemark!

func getPlaceMarkInfo(coordinate: CLLocationCoordinate2D, completion: (superPlace: MKPlacemark?) -> ()) {
    let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
    geocoder.reverseGeocodeLocation(location) { (arrayPlaceMark, error) -> Void in
        if error == nil {
            let firstPlace = arrayPlaceMark!.first!
            let addressDictionaryPass = firstPlace.addressDictionary as! [String : AnyObject]

            self.superPlace = MKPlacemark(coordinate: location.coordinate, addressDictionary: addressDictionaryPass)
            completion(superPlace: superPlace)
        } else {
            completion(superPlace: nil)
        }
    } 
}



回答2:


This comes up over and over and over. The short answer is "you can't."

The result is not available when your function returns. The async call takes place in the background.

What you want to do is refactor your returnPlacemarkInfo function to take a completion closure.

I have been working in Objective-C lately, so my Swift is a little rusty, but it might look like this:

 func fetchPlaceMarkInfo(
  coordinate: CLLocationCoordinate2D, 
  completion: (thePlacemark: MKPlacemark?) -> () )
 {
 }

Then when you call it, pass in a completion closure that gets invoked once the placemark is available.

EDIT:

I wrote a demo project and posted it on Github that simulates handling an async network download. Take a look at

https://github.com/DuncanMC/SwiftCompletionHandlers

Specifically look at the method asyncFetchImage(), which does almost exactly what we are talking about: Uses an async method internally, and takes a completion block that it calls once the async load is done.



来源:https://stackoverflow.com/questions/33525795/how-to-return-value-after-the-execution-of-the-block-swift

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!