为啥我的代码在线程 6:NSOperationQueue 中运行时会崩溃?

Posted

技术标签:

【中文标题】为啥我的代码在线程 6:NSOperationQueue 中运行时会崩溃?【英文标题】:Why is my code crashing when I run it in Thread 6: NSOperationQueue?为什么我的代码在线程 6:NSOperationQueue 中运行时会崩溃? 【发布时间】:2015-05-31 16:37:04 【问题描述】:
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(code=EXC_1386_INVOP, subcode=0x0)。

非常感谢。

【问题讨论】:

【参考方案1】:

您收到此错误是因为响应不是 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.ioAPI documentation 中的说明在 URL 中包含纬度和经度,否则您将收到非 JSON 错误响应。即使您修复了 URL 以避免此错误,您仍然应该像上面那样对错误进行一些优雅的处理,否则您的应用程序可能会在出现任何服务器问题时崩溃。

【讨论】:

谢谢 Rob,这很有帮助。但我只是想知道,当你说使用错误参数时,我认为你指的是你的可选初始化 'var error: NSError?',但你为什么要这样做?错误不是已经在完成处理程序中初始化了吗?? 有两个错误对象:有一个与网络请求相关联,但还有error 参数到JSONObjectWithData。我很担心后者。如果网络请求成功(即没有 NSError 对象传递给闭包),您仍然需要一些变量来保存 JSON 解析生成的任何错误。

以上是关于为啥我的代码在线程 6:NSOperationQueue 中运行时会崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

为啥相同的代码在我的 BackGroundWorker 线程中比在我的 GUI 线程中慢得多?

为啥我的多线程代码没有更快?

为啥我的代码中断线程泄漏?

为啥我的 Eigen 代码不能随更多线程扩展

为啥我的进程列表在运行 aiohttp 时会显示多个线程?

为啥重新执行我的多线程代码后输出不一样?