【问题标题】:Function returns before code finishes running in swift函数在代码完成快速运行之前返回
【发布时间】:2015-06-29 03:42:34
【问题描述】:

我创建了一个类函数,其中包含一个闭包,可将位置坐标反向编码为地址字符串。我最初是在视图控制器中编写的,但我需要在几个地方运行这段代码。

我的问题是类函数在闭包运行之前返回字符串,所以返回的字符串是空白的。我有什么方法可以解决这个问题?有没有比使用类函数更好的方法来组织我的代码?

import CoreLocation
class LocationUtil: CLLocation {
    class func getLocationAddress(location:CLLocation?) -> NSString {
        var geocoder = CLGeocoder()
        var addressString : String = ""

        if location != nil {
            geocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error)->Void in
                var placemark:CLPlacemark!

                if error == nil && placemarks.count > 0 {
                    placemark = placemarks[0] as CLPlacemark

                    if placemark.subThoroughfare != nil {
                        addressString = placemark.subThoroughfare + " "
                    }
                    if placemark.thoroughfare != nil {
                        addressString = addressString + placemark.thoroughfare + ", "
                    }
                    if placemark.locality != nil {
                        addressString = addressString + placemark.locality + ", "
                    }
                    if placemark.administrativeArea != nil {
                        addressString = addressString + placemark.administrativeArea + " "
                    }
                    if placemark.postalCode != nil {
                        addressString = addressString + placemark.postalCode + " "
                    }
                    if placemark.country != nil {
                        addressString = addressString + placemark.country
                    }

                }
                println("Address in closure: \(addressString)") //prints addresss
            })
        }
        println("Address out of closure: \(addressString)") // doesn't print address
        return addressString //this returns nothing
    }
}

【问题讨论】:

    标签: ios swift asynchronous closures


    【解决方案1】:

    geocoder.reverseGeocodeLocation异步运行并仅在 完成后调用 completionHandler

    因此,获取返回值显然不是一种选择。相反,接受闭包作为类函数的输入/参数

    class func getLocationAddress(location: CLLocation, getLocCompletionHandler : (addressString : String?, error : NSError?) -> Void) {
    
           geocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error)->Void in
                //Your current code
                //...
                //...
                println("Address: \(addressString)")
                //Instead of returning the address string, call the 'getLocCompletionHandler'
                getLocCompletionHandler(addressString: addressString, error: error)
    
            })
    }
    

    当你调用这个函数时,不要使用返回值,而是等待闭包被调用:

    LocationUtil.getLocationAddress(currentLocation, completionHandler: { (addressObject, error) -> Void in
        println("Address: \(addressString)")
        //OR handle the error appropriately
    }
    

    阅读 closures 以更好地理解这个概念。

    就代码组织而言,在这种情况下,类函数是一个不错的选择。

    【讨论】:

    • 谢谢,我能够按照这个并让它工作!仍在努力解决我完全理解闭包的心理障碍。
    • 有趣的是,你应该说你对闭包有一个心理“障碍”。关闭者本质上就像来自 ObjC 的“障碍”
    【解决方案2】:

    你应该在你的

    中返回completionHandler
    geocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error)->Void in
    

    函数完成后将调用completionHandler。为此,您还应该让自己的函数异步返回。

    这是必需的,因为您的 reverseGeocodeLocation 函数是异步运行的。您的主线程将继续运行您的getLocationAddress,因此它将返回字符串,但它是空的,因为它是在异步函数完成之前返回的。

    【讨论】:

      猜你喜欢
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 2023-02-23
      • 1970-01-01
      • 2018-02-08
      • 1970-01-01
      • 2021-08-02
      • 2023-03-13
      相关资源
      最近更新 更多