【问题标题】:Unexpectedly found nil while unwrapping an optional value while reading JSON [closed]在读取 JSON 时打开可选值时意外发现 nil [关闭]
【发布时间】:2016-01-14 15:13:42
【问题描述】:

我收到错误“致命错误:在展开可选值时意外发现 nil”。我正在尝试从我的服务器获取 JSON 作为字典。如果数据为 nil,如何抛出错误?

    let jsonUrl = "jsonurl"
    let session = NSURLSession.sharedSession()
    let shotsUrl = NSURL(string: jsonUrl)
    let task = session.dataTaskWithURL(shotsUrl!, completionHandler: {
        (data,response,error) -> Void in
        do {
            let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) // Get error
            dispatch_async(dispatch_get_main_queue()) {
                for newData in json as! [Dictionary<String, AnyObject>] {
                   // do stuff
                }
            }
        } catch {

        }
    })
    task.resume()

编辑:澄清一下,我在没有互联网连接时进行测试,它应该忽略抛出的错误,而是给出错误。我试过了

guard let data = data else { return }
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)

但它在 let json 行上显示“无法强制解开可选类型 'NSData'”

【问题讨论】:

标签: ios json swift


【解决方案1】:

data 参数处理完成处理程序中返回的error 而不是 guard。 如果没有error,则可以安全地解开data

let task = session.dataTaskWithURL(shotsUrl!, completionHandler: {
    (data,response,error) -> Void in
    if error != nil {
      // do proper error handling

    } else {
        do {
        let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
        ...

并在catch 范围内添加适当的错误处理。这似乎很烦人,但可能非常有用。 ;-)

【讨论】:

    【解决方案2】:

    您通过说data! 来强制解包数据。这意味着如果它期望数据不为零,如果没有互联网连接,它将永远是零。您至少需要在强制展开之前检查数据是否为零,然后处理您希望如何创建对象(如果它是零)。

    if data != nil {
            do {
                let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) // Get error
                dispatch_async(dispatch_get_main_queue()) {
                    for newData in json as! [Dictionary<String, AnyObject>] {
                       // do stuff
                    }
                }
            } catch {
    
            }
    } else {
        //handle object creation if data is nil
    }
    

    【讨论】:

    • 这是解决您的强制展开问题的最小解决方案,您的代码在处理来自 dataTask 完成的错误时远非最佳实践。你也应该在类似的事情中检查你的错误,如果错误以if error != nil 退出并检查你得到的响应,则处理它们。
    猜你喜欢
    • 2015-05-05
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-11
    相关资源
    最近更新 更多