Swift - 在函数之间设置值时遇到 nil 问题
Posted
技术标签:
【中文标题】Swift - 在函数之间设置值时遇到 nil 问题【英文标题】:Swift - Trouble with getting nil when setting values in between functions 【发布时间】: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
之前,您不能假设位置已更新。
【参考方案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 是的,这是真的。但我更愿意在与一个明确的初学者打交道时进行解释,而不是用不必要的技术性措辞让他雪上加霜。以上是关于Swift - 在函数之间设置值时遇到 nil 问题的主要内容,如果未能解决你的问题,请参考以下文章
Swift/Xcode 9 - 应用内购买 - 在展开可选值时意外发现 nil
Swift 和 UILabel - 致命错误:在展开可选值时意外发现 nil
Swift - 在展开可选值时意外发现 nil - 从委托调用变量