Swift 在闭包外声明的变量在闭包内更新,但在闭包外访问时 returns 默认值?

Swift variable declared outside closure is updated inside closure but when accessed outside closure it returns the default value?

所以我调用的函数应该只是 return 输入地址的经度。我会把它附加在这里,这样你就可以看到它,然后我会在代码后面评论它:

func getLongitude(address: String) -> Double {
    var longitude: Double = 0.0
    let geocoder = CLGeocoder()
    geocoder.geocodeAddressString(address) {
        placemarks, error in 
        let placemark = placemarks?.first
        longitude = placemark?.location?.coordinate.longitude ?? 0.0
        print("The testing longitude is \(longitude)")
    }
    return longitude
}

如您所见,我将经度变量声明为默认值 0.0。在函数内的闭包中,我更新了经度。 print 语句确认经度已在该函数的闭包中更新。当在此闭包之外使用 return 语句访问经度时,它再次 returns 0.0(我相信经度的值在闭包之外没有发生变化,但我不知道如何修复这个)。任何帮助将不胜感激!

请使用制表符使您的代码更易于阅读。

无论如何 geocoder.geocodeAddressString(address) 是一个带有回调的方法,在这个回调方法中你有地标。您的 return 不会等待该回调,因为计算坐标需要时间,因此您在开始时设置的 returns 0.0。


编辑: 自您在评论中提问后的更长版本:

CLGeocoder() 的函数 geocodeAddressString 实际上有 2 个参数:地址和所谓的回调。回调只是一种在任务(在本例中为计算地标)完成时调用的方法。 Swift 允许您使用 "swifty" 语法编写回调,但实际上它看起来像

geocoder.geocodeAddressString(address, callAfterFinishGeocoding)

func callAfterFinishGeocoding(_ placemark: Placemark) {
   // do stuff with placemark
}

如您所见,我们将地理编码函数传递给完成后调用的另一个函数。 callAfterFinishGeocoding的参数定义在geocodeAddressString中。它看起来类似于:

callback: @escaping (_ placeMark: Placemark) -> Void

这意味着回调应该是一个接受地标和 returning Void 的函数。跳转到方法的定义,看看它想要什么样的函数作为参数。

也可以在这里阅读更多内容:

闭包是异步执行的,即在 return 语句是 运行 之后。将您的功能更改为

func getLongitude(address: String, completion: @escaping (Double)->Void)
 {
     var longitude: Double = 0.0
     let geocoder = CLGeocoder()

    geocoder.geocodeAddressString(address)
    {
        placemarks, error in
        let placemark = placemarks?.first
        longitude = placemark?.location?.coordinate.longitude ?? 0.0
        print("The testing longitude is \(longitude)")

        completion(longitude)
    }
 }