CLGeocoder 错误 EXC_BAD_INSTRUCTION
CLGeocoder error EXC_BAD_INSTRUCTION
我正在使用 CLGeocoder reverseGeocodeLocation。我在 运行 后崩溃了大约 5-10 分钟(没有明显的模式)并随机崩溃。这是我的代码:
if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
let currentLatCoord = manager.location?.coordinate.latitude
let currentLongCoord = manager.location?.coordinate.longitude
CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: currentLatCoord!, longitude: currentLongCoord!)) { (placemarks, error) -> Void in
if error != nil {
print(error)
return
}
let placeArray = placemarks as [CLPlacemark]!
var placeMark: CLPlacemark
placeMark = placeArray![0]
self.locationLabel.text = String(placeMark.addressDictionary?["Thoroughfare"]!)
}
}
此外,为了提供帮助,这里是该行和错误的图片:
我认为您需要一些可选绑定:
if let thoroughfare = placeMark.addressDictionary?["Thoroughfare"] as? String {
self.locationLabel.text = thoroughfare
}
我猜测地址字典中可能没有 "Thoroughfare"
键,并且您正在为 String
的指定初始值设定项提供 nil
值。
当 CLGeocoder
完成其反向地理编码时,您的代码片段中正在更新的视图是否有可能不在屏幕上(已处置)?如果您将出口定义为隐式展开的可选:
@IBOutlet var locationLabel : UILabel!
我想知道它是否已经设置为 nil
,但是由于爆炸 (!
),编译器没有让您检查。
但是,当然,如果当您崩溃时您的视图仍在屏幕上,这可能不是问题所在。
您向我们提供了代码示例:
let currentLatCoord = manager.location?.coordinate.latitude
let currentLongCoord = manager.location?.coordinate.longitude
CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: currentLatCoord!, longitude: currentLongCoord!)) { (placemarks, error) -> Void in
if error != nil {
print(error)
return
}
let placeArray = placemarks as [CLPlacemark]!
var placeMark: CLPlacemark
placeMark = placeArray![0]
self.locationLabel.text = String(placeMark.addressDictionary?["Thoroughfare"]!)
}
如果使用 if let
结构,您可以更优雅地处理 nil
值:
CLGeocoder().reverseGeocodeLocation(manager.location!) { placemarks, error in
guard error == nil else {
print(error)
return
}
if let placemark = placemarks?.first {
self.locationLabel.text = placemark.thoroughfare
}
}
当然,如果您重复调用它,我不会每次都重新实例化一个新的 CLGeocoder
,但希望这能说明模式。
但是如您所见,您可以避免从位置 属性 中提取纬度和经度,只需直接使用 manager.location
即可创建新的 CLLocation
对象。同样,您可以使用 thoroughfare
属性,这样您就无需强制转换 addressDictionary
值。
Craig 上面提到的关键观察是谨慎避免使用 !
强制展开运算符,除非您确定变量永远不会是 nil
。同样,不要使用 [0]
语法,除非你知道数组中至少有一个项目(这就是我使用 first
的原因,这是一个我可以轻松测试的选项).
坦率地说,我什至会确保 location
有效(不是 nil
并且具有非负值 horizontalAccuracy
,因为负值表示坐标是无效):
if let location = manager.location where location.horizontalAccuracy >= 0 {
CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
guard error == nil else {
print(error)
return
}
if let placemark = placemarks?.first {
self.locationLabel.text = placemark.thoroughfare
}
}
}
我正在使用 CLGeocoder reverseGeocodeLocation。我在 运行 后崩溃了大约 5-10 分钟(没有明显的模式)并随机崩溃。这是我的代码:
if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
let currentLatCoord = manager.location?.coordinate.latitude
let currentLongCoord = manager.location?.coordinate.longitude
CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: currentLatCoord!, longitude: currentLongCoord!)) { (placemarks, error) -> Void in
if error != nil {
print(error)
return
}
let placeArray = placemarks as [CLPlacemark]!
var placeMark: CLPlacemark
placeMark = placeArray![0]
self.locationLabel.text = String(placeMark.addressDictionary?["Thoroughfare"]!)
}
}
此外,为了提供帮助,这里是该行和错误的图片:
我认为您需要一些可选绑定:
if let thoroughfare = placeMark.addressDictionary?["Thoroughfare"] as? String {
self.locationLabel.text = thoroughfare
}
我猜测地址字典中可能没有 "Thoroughfare"
键,并且您正在为 String
的指定初始值设定项提供 nil
值。
当 CLGeocoder
完成其反向地理编码时,您的代码片段中正在更新的视图是否有可能不在屏幕上(已处置)?如果您将出口定义为隐式展开的可选:
@IBOutlet var locationLabel : UILabel!
我想知道它是否已经设置为 nil
,但是由于爆炸 (!
),编译器没有让您检查。
但是,当然,如果当您崩溃时您的视图仍在屏幕上,这可能不是问题所在。
您向我们提供了代码示例:
let currentLatCoord = manager.location?.coordinate.latitude
let currentLongCoord = manager.location?.coordinate.longitude
CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: currentLatCoord!, longitude: currentLongCoord!)) { (placemarks, error) -> Void in
if error != nil {
print(error)
return
}
let placeArray = placemarks as [CLPlacemark]!
var placeMark: CLPlacemark
placeMark = placeArray![0]
self.locationLabel.text = String(placeMark.addressDictionary?["Thoroughfare"]!)
}
如果使用 if let
结构,您可以更优雅地处理 nil
值:
CLGeocoder().reverseGeocodeLocation(manager.location!) { placemarks, error in
guard error == nil else {
print(error)
return
}
if let placemark = placemarks?.first {
self.locationLabel.text = placemark.thoroughfare
}
}
当然,如果您重复调用它,我不会每次都重新实例化一个新的 CLGeocoder
,但希望这能说明模式。
但是如您所见,您可以避免从位置 属性 中提取纬度和经度,只需直接使用 manager.location
即可创建新的 CLLocation
对象。同样,您可以使用 thoroughfare
属性,这样您就无需强制转换 addressDictionary
值。
Craig 上面提到的关键观察是谨慎避免使用 !
强制展开运算符,除非您确定变量永远不会是 nil
。同样,不要使用 [0]
语法,除非你知道数组中至少有一个项目(这就是我使用 first
的原因,这是一个我可以轻松测试的选项).
坦率地说,我什至会确保 location
有效(不是 nil
并且具有非负值 horizontalAccuracy
,因为负值表示坐标是无效):
if let location = manager.location where location.horizontalAccuracy >= 0 {
CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
guard error == nil else {
print(error)
return
}
if let placemark = placemarks?.first {
self.locationLabel.text = placemark.thoroughfare
}
}
}