【问题标题】:Swift - Trouble with getting nil when setting values in between functionsSwift - 在函数之间设置值时遇到 nil 问题
【发布时间】:2018-02-13 19:58:08
【问题描述】:

您好,当我编写一个简单的位置接收类时,我似乎只能将 nil 作为我的位置变量。我已经搜索了一段时间的堆栈溢出并尝试了许多解决方案,但我似乎无法修复它。

下面是我的代码。我正在尝试方法,一种是在我的 didUpdateLocations 方法的结构中设置变量。另一种只是更新一个变量userLocation。目前两者都只是给出我的 nil,我不知道为什么。

class SendLocation:  NSObject, CLLocationManagerDelegate{


var userLocation: CLLocation? = nil
var locationManager:CLLocationManager!


struct LocationStruct{
    var latitude:CLLocationDegrees?, longitude:CLLocationDegrees?
}

var locationStruct = LocationStruct()


func sendLocationPost(){
    determineCurrentLocation()
    print(userLocation) // This is nil
    print(locationStruct.latitude) // This is nil
    print(locationStruct.longitude) // This is nil

}

func determineCurrentLocation(){
    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()
    if CLLocationManager.locationServicesEnabled(){
        locationManager.startUpdatingLocation()
    }
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
    userLocation = locations[0] as CLLocation
    print(userLocation) // This IS NOT nil
    locationStruct.latitude=userLocation?.coordinate.latitude
    locationStruct.longitude=userLocation?.coordinate.longitude

}

提前感谢您的帮助,因为我知道这将是一些简单/愚蠢的事情

【问题讨论】:

  • 您何时何地致电sendLocationPost
  • 哪个先打印,nil 还是 non-nil?
  • @PhillipMills Mills 既然你提到了它,那么 nils 打印首先
  • 有道理。在致电didUpdateLocations 之前,您不能假设位置已更新。

标签: ios swift delegates core-location cllocationmanager


【解决方案1】:

这只是理解事情需要时间的问题。您正在向前迈进,就好像开始获取位置时会立即为您提供位置。但它没有:

func sendLocationPost(){
    determineCurrentLocation()
    // so now things start... but they take _time_...!
    print(userLocation) // This is nil
    // because it's _too soon!_
    // ...
}

当您第一次拨打determineCurrentLocation 时,传感器需要很长时间才能预热并到达合适的位置:

func determineCurrentLocation(){
    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()
    if CLLocationManager.locationServicesEnabled(){
        locationManager.startUpdatingLocation()
        // SLOWLY... things now start to happen
    }
}

最后,经过一段重要的时间,也许,只是也许,我们终于开始得到一些更新,再过一段时间,也许它们不是零:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
    userLocation = locations[0] as CLLocation
    print(userLocation) // This IS NOT nil
    locationStruct.latitude=userLocation?.coordinate.latitude
    locationStruct.longitude=userLocation?.coordinate.longitude

}

现在我们找到了位置。但与此同时,您在sendLocationPost 中的代码很久以前就结束了,并得到了nil

【讨论】:

  • 这是一个非常好的答案,谢谢。我没想到 startUpdatingLocations() 会花时间。
  • 比获取位置更重要的是它是异步发生的,所以执行可以在发生时继续。
  • @BallpointBen 这就是我所说的“花时间”的意思。 “异步”的意思实际上仅此而已。正如我的回答所示,我们在sendLocationPost 中继续下一步determineCurrentLocation 开始的操作有机会更新位置之前。
  • 异步具体表示执行不会阻塞当前线程。冗长的任务不需要异步执行。
  • @BallpointBen 是的,这是真的。但我更愿意在与一个明确的初学者打交道时进行解释,而不是用不必要的技术性措辞让他雪上加霜。
猜你喜欢
  • 1970-01-01
  • 2020-04-13
  • 2016-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
相关资源
最近更新 更多