swift2 如何在块执行后返回值?Swift

ecbunoof  于 2022-11-06  发布在  Swift
关注(0)|答案(2)|浏览(167)

我想从函数中得到一个值。函数中有一个块。当块执行时,函数已经返回了值。我尝试了许多不同的方法,但它们都没有帮助我。我使用了NSOperation和Dispatch。函数总是返回值,直到块执行。

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
}
whlutmcx

whlutmcx1#

由于reverseGeocodeLocation函数是异步运行的,因此您不能简单地返回到此处,因此您需要使用自己的完成块:

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)
        }
    } 
}
insrf1ej

insrf1ej2#

这个问题一遍又一遍地出现,简短的回答是“你不能”。
当函数返回时,结果不可用。异步调用在后台进行。
您需要做的是重构returnPlacemarkInfo函数,以获取一个完成闭包。
我最近一直在用Objective-C,所以我的Swift有点生疏了,但它看起来可能是这样的:

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

然后,当调用它时,传入一个完成闭包,一旦地标可用,就会调用该闭包。

编辑:

我写了一个演示项目,并将其发布在Github上,模拟处理异步网络下载。
https://github.com/DuncanMC/SwiftCompletionHandlers
具体来看一下asyncFetchImage()方法,它几乎完全实现了我们所讨论的内容:在内部使用异步方法,并获取一个完成块,在异步加载完成后调用该块。

相关问题