How to solve this EXC_BAD_ACCESS(code=EXC_i386_GPFLT )in swift programming

匿名 (未验证) 提交于 2019-12-03 02:26:02

问题:

this is my code.getting this EXC_BAD_ACCESS(code=EXC_i386_GPFLT).I don'n know how to find and solve plz help me ...application getting crash when get longitude

mapServerRequest="Hyderabad,india" var mapAddress:NSString=mapServerRequest mapAddress.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet())      println(mapAddress) var urlpath=NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address=%@", mapAddress)      println(urlpath) var url = NSURL.URLWithString(urlpath)     println(url) var jsonData:NSData=NSData(contentsOfURL:url)         if(jsonData != nil)     {         var error:NSError=NSError(coder: nil)         var result:NSDictionary=NSJSONSerialization .JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary         //println(result)         if (error != nil)         {             mapServerResultArray=result.valueForKey("results") as NSMutableArray            // println(mapServerResultArray)          }       var longitud:NSString             longitud=mapServerResultArray.objectAtIndex(0).valueForKey("geometry").valueForKey("location").valueForKey("lng")as NSString          var latitud :NSString = (mapServerResultArray .objectAtIndex(0).valueForKey("geometry").valueForKey("location").valueForKey("lat")) as NSString         placeName=mapServerResultArray .objectAtIndex(0).valueForKey("formatted_address") as NSString         var longitude:Float=longitud.floatValue         var latitude:Float=latitud.floatValue         self.zoomMapAndCenterAtLatitude(latitude)         self.zoomMapAndCenterAtLongitud(longitude)  

回答1:

Your problem here is that most of the operations you are performing can return nil, which will crash Swift if you try and use it as a non-nil value. You need to be explicit about testing for nil. The sledgehammer way of doing it would be

let mapAddress = "Hyderabad,india"  let url = NSURL.URLWithString("http://maps.googleapis.com/maps/api/geocode/json?address=\(mapAddress)")  let jsonData = NSData(contentsOfURL:url)  var latitude = NSNumber(double: 0.0) var longitude = NSNumber(double: 0.0) var success = false  if jsonData != nil {     if let result = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSDictionary {         if let mapServerResultArray = result.valueForKey("results") as? NSArray {             if let geometry = mapServerResultArray[0].valueForKey("geometry") as? NSDictionary {                 if let location = geometry.valueForKey("location") as? NSDictionary {                     if let lat = location.valueForKey("lat") as? Float {                         latitude = lat                         if let lng = location.valueForKey("lng") as? Float {                             longitude = lng                             success = true                         }                     }                 }             }         }     } } if success {     println("Latitude = \(latitude), longitude=\(longitude)") } else {     println("Failed") } 

... however that is ugly. As this routine may or may not find any of the keys, at the end you may or may not have a valid pair of coordinates. This is exactly what Optionals are for. Consider rewriting it as a function that returns an optional:

struct Coordinate { // Or use any of Cocoa's similar structs     var latitude: Double     var longitude: Double }  func getCoordsOf(#address: String) -> Coordinate? {     let url = NSURL.URLWithString("http://maps.googleapis.com/maps/api/geocode/json?address=\(address)")     let jsonData = NSData(contentsOfURL:url)     if jsonData == nil { return nil }      let result = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary     if result == nil { return nil }      if let geometry = result.valueForKey("results").valueForKey("geometry") as? NSArray {         if geometry.count > 0 {             let lat = geometry[0].valueForKey("location")?.valueForKey("lat")?.doubleValue             let lng = geometry[0].valueForKey("location")?.valueForKey("lng")?.doubleValue              if (lat != nil) && (lng != nil) {                 return Coordinate(latitude: lat!, longitude: lng!)             }         }     }     return nil }  if let coord = getCoordsOf(address: "Hyderabad,india") {     // ... do something } 

This uses Optional Chaining (?) to lessen the testing, but we have to break it at geometry because we need that to be an array, as we need to access a specific element of it (and, of course, should test that it isn't an empty array!)

p.s. - ironically, your test on error != nil does nothing, as you did not send error to the JSONObjectWithData routine.



回答2:

In that type of situation you can convert latitude to string. Updated code:

 mapServerRequest="Hyderabad,india"     var mapAddress:NSString=mapServerRequest     mapAddress.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet())          println(mapAddress)     var urlpath=NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address=%@", mapAddress)          println(urlpath)     var url = NSURL.URLWithString(urlpath)         println(url)     var jsonData:NSData=NSData(contentsOfURL:url)             if(jsonData != nil)         {             var error:NSError=NSError(coder: nil)             var result:NSDictionary=NSJSONSerialization .JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary             //println(result)             if (error != nil)             {                 mapServerResultArray=result.valueForKey("results") as NSMutableArray                // println(mapServerResultArray)              }           var longitud:NSString                 longitud=NSString(format:mapServerResultArray.objectAtIndex(0).valueForKey("geometry").valueForKey("location").valueForKey("lng"))             var latitud :NSString  latitud=NSString(format:(mapServerResultArray .objectAtIndex(0).valueForKey("geometry").valueForKey("location").valueForKey("lat")))             placeName=NSString(format:mapServerResultArray .objectAtIndex(0).valueForKey("formatted_address"))             var longitude:Float=longitud.floatValue             var latitude:Float=latitud.floatValue             self.zoomMapAndCenterAtLatitude(latitude)             self.zoomMapAndCenterAtLongitud(longitude) 


回答3:

Short answer:

enable Zombies in the Scheme and it will enable a breakpoint and proper reason will be displayed in the logs

Technical reason:

You are trying to do something which in not allowed in the architecture refer this What's the meaning of exception code "EXC_I386_GPFLT"?



回答4:

This response you are getting :"http://maps.googleapis.com/maps/api/geocode/json?address=Hyderabad,india"

You can fetch like below:

Here jsondict is your respnse from api

NSArray *results = [jsonDict objectForKey:@"results"];     NSDictionary *geometry = [[results objectAtIndex:0] valueForKey:@"geometry"]; NSArray *location = [geometry objectForKey:@"location"]; float lat = [[location valueForKey:@"lat"] floatValue];     float lng = [[location valueForKey:@"lng"] floatValue]; 


回答5:

use this :

var longitud:NSString =(mapServerResultArray.objectAtIndex(0).valueForKey("geometry").objectForKey("location").valueForKey("lng")) as NSString  var latitud :NSString =  (mapServerResultArray .objectAtIndex(0).valueForKey("geometry").objectForKey("location").valueForKey("lat")) as NSString         placeName=mapServerResultArray .objectAtIndex(0).valueForKey("formatted_address") as NSString         var longitude:Float=longitud.floatValue         var latitude:Float=latitud.floatValue         self.zoomMapAndCenterAtLatitude(latitude)         self.zoomMapAndCenterAtLongitud(longitude)  


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!