我遇到了一个奇怪的错误,无法解决这个问题。我做了一个简单的天气应用程序,根据用户坐标更新天气。在模拟器上,一切运行都很完美但是在设备上我得到了下面的错误。
我在viewDidLoad:
上方的类范围中声明了我的位置管理器let locationManager = CLLocationManager()
我的viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startMonitoringSignificantLocationChanges()
tableView.delegate = self
tableView.dataSource = self
currentWeather = CurrentWeather()
}
我在viewDidAppear:
之后调用此函数 override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
locationAuthStatus()
}
func locationAuthStatus() {
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
currentLocation = locationManager.location
Location.sharedInstance.latitude = currentLocation.coordinate.latitude
Location.sharedInstance.longitude = currentLocation.coordinate.longitude
currentWeather.downloadWeatherDetails {
self.downloadForecastData {
self.updateMainUI()
}
}
} else {
locationManager.requestWhenInUseAuthorization()
locationAuthStatus()
}
}
如果用户尚未获得授权,则错误是上述else语句中的第一行。如果您在崩溃后重新运行应用程序,天气将更新正常。任何帮助,将不胜感激。谢谢。
更新
感谢评论中的建议,我能够解决我的错误。我将代码从locationAuthStatus移到了locationManager(_ manager:CLLocationManager,didChangeAuthorization。
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
currentLocation = locationManager.location
Location.sharedInstance.latitude = currentLocation.coordinate.latitude
Location.sharedInstance.longitude = currentLocation.coordinate.longitude
currentWeather.downloadWeatherDetails {
self.downloadForecastData {
self.updateMainUI()
}
}
} else {
locationManager.requestWhenInUseAuthorization()
}
}
谢谢大家的帮助。
答案 0 :(得分:3)
我认为您的代码忽略了某些位置操作是异步的。
requestWhenInUseAuthorization
,然后立即进行递归。 requestWhenInUseAuthorization
是异步的并立即返回。在执行递归之前状态不会更改,因此您可以重复调用它。我怀疑这是导致错误的问题。在这里使用didChangeAuthorization
。locationManager.location
阅读地理位置的方式也很可疑。您应该异步获取该位置以获取当前位置。您应该使用requestLocation()
阅读CLLocationManagerDelegate以了解如何在CoreLocation中处理异步操作
答案 1 :(得分:0)
EXEC_BAD_Access表示取消引用非法内存地址。在这种情况下,内存地址是位置管理器的地址。要诊断问题,我们需要知道创建位置管理器的位置。
由于问题不是显示的代码块的本地问题,而是在设置位置管理器时的某些早期问题,因此无法从此处诊断出问题。
请提供: 1)最初设置位置管理器属性的位置 2)位置管理器的任何地方都被更改。
还要确保您没有做任何异常事情,例如尝试在不安全的操作(例如segue)中访问属性。
确保所有权利配置正确,并检查堆栈跟踪以查看位置管理员是否正在调用从其下方消失的任何内容。
答案 2 :(得分:0)
您是否已将NSLocationWhenInUseUsageDescription
和NSLocationAlwaysUsageDescription
添加到Info.plist
?
没有这些属性可能会导致设备崩溃