1
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = NSURL(string: "https://api.forecast.io/forecast/MYKEYHERE/")
        let session = NSURLSession.sharedSession()
        let task: NSURLSessionDownloadTask = session.downloadTaskWithURL(url!, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
            if error == nil {
                let data = NSData(contentsOfURL: location)
                let json: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: nil) as! NSDictionary!
                println(json)
            }
        })
        task.resume()

    }

这是天气 API 的下载任务的代码。只是想知道为什么我收到错误:

线程 6:EXC_BAD_INSTRUCTION(代码=EXC_1386_INVOP,子代码=0x0)。

非常感谢。

4

1 回答 1

0

您收到此错误是因为响应不是 JSON(或 JSON 不是字典)。因此,在解析 JSON 时,使用可选绑定来优雅地处理nil或非字典错误,如果失败,可能会检查响应主体,例如:

let task = session.downloadTaskWithURL(url!) { location, response, error in
    if error == nil {
        let data = NSData(contentsOfURL: location)
        var error: NSError?
        if let json = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: &error) as? NSDictionary {
            println("json = \(json)")
        } else {
            println("error = \(error)")
            let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
            println("not json; responseString = \(responseString)")
            println(response)
        }
    }
}
task.resume()

另外,请注意,在使用 时JSONObjectWithData,您不仅要优雅地检查错误,而且通常还希望使用该error参数,如上所述。

顺便说一句,请确保按照forecast.io API 文档中的说明在 URL 中包含纬度和经度,否则您将收到非 JSON 错误响应。即使您修复了 URL 以避免此错误,您仍然应该像上面那样对错误进行一些优雅的处理,否则您的应用程序可能会在出现任何服务器问题时崩溃。

于 2015-05-31T16:47:03.380 回答