如何在swift编程中解决这个EXC_BAD_ACCESS(代码= EXC_i386_GPFLT)

时间:2014-07-19 06:05:48

标签: ios map swift

这是我的代码。注意这个EXC_BAD_ACCESS(代码= EXC_i386_GPFLT)。我不知道如何找到并解决plz帮助我...应用程序在获得经度时崩溃

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) 

5 个答案:

答案 0 :(得分:6)

简短回答:

启用Scheme中的Zombies并启用断点,并在日志中显示正确的原因

技术原因:

您正在尝试执行架构中不允许的操作 请参阅此What's the meaning of exception code "EXC_I386_GPFLT"?

答案 1 :(得分:3)

你的问题在于,你正在执行的大多数操作都可以返回nil,如果你试图将它作为非零值使用会导致Swift崩溃。您需要明确测试nil。大锤的做法是

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")
}

......然而这很难看。由于此例程可能会或可能不会找到任何键,但最后可能<或> 具有有效的坐标对。这正是Optionals的用途。考虑将其重写为返回可选项的函数:

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
}

这使用了可选链接(?)来减少测试,但我们必须在geometry处理它,因为我们需要这是一个数组,因为我们需要访问它的特定元素(当然,应该测试它不是一个空数组!)

P.S。 - 具有讽刺意味的是,你对error != nil的测试什么也没做,因为你没有将error发送到JSONObjectWithData例程。

答案 2 :(得分:1)

在这种情况下,您可以将纬度转换为字符串。  更新的代码:

 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 :(得分:-4)

您收到的回复是:“http://maps.googleapis.com/maps/api/geocode/json?address=Hyderabad,india

你可以像下面这样获取:

这里的jsondict是你对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];

答案 4 :(得分:-5)

使用它:

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)