在Swift中检查可选项是否为nil

3

如何在Swift中检查可选项是否为nil?

我正在尝试评估解析JSON是否成功。当传递无效的JSON时,应该打印错误消息,但是会出现EXC_BAD_INSTRUCTION错误。

func parseJson(data: NSData) {
    var error: NSError?
    var json: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
    if let err = error {
        println("error parsing json")
        return
    }
    println("json parsed successfully")
}

尝试使用有效的JSON运行(正常工作):
parseJson(NSData(data: "{}".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)))

尝试使用无效的JSON:

parseJson(NSData(data: "123".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)))

我在处理可选项时是否有所遗漏?

4个回答

6
崩溃发生的原因是如果出现错误,JSONObjectWithData会返回nil。然后您尝试将nil转换为NSDictionary。这样做是可行的:
func parseJson(data: NSData) {
    var error: NSError?
    var json : AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error)
    if let err = error {
        println("error parsing json")
        return
    }
    println("json parsed successfully")
    var jsonDict = json as NSDictionary
}

如果您愿意,可以将变量类型var json切换为NSDictionary。这样它就可以直接处理nil值了。要做到这一点,您只需在"as"关键字后面添加一个问号'?'即可:
func parseJson(data: NSData) {
    var error: NSError?
    var json: NSDictionary? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as? NSDictionary
    if let err = error {
        println("error parsing json")
        return
    }
    // unwrap the optional value
    if let jsonDictionary = json {
        println("json parsed successfully")
        // use the dictionary
    }
}

1
我认为这个解决方案是最好的。它按设计使用了JSONObjectWithData API,并且是最简洁的。它展示了隐式解包可选项的好处的一个很好的例子。 - mbeaty

1
我稍微重构了你的代码:

func parseJson(data: NSData) {
    var error: NSError?
    var json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error)
    if let jsonDict: NSDictionary = json as? NSDictionary{
        println("json parsed successfully")
        //do something with the nsdictionary...
    }
    else{
        println("error parsing json")
    }

}
parseJson(NSData(data: "{}".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)))
parseJson(NSData(data: "123".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)))

问题不在于您的if代码,而是在方法失败时将json作为NSDictionary进行处理。此外,此代码现在检查是否返回了NSDictionary,而不是检查错误本身。

0

我一直遇到 fatal error: unexpectedly found nil while unwrapping an Optional value 的问题,直到我将 NSDictionary 类型转换设置为可选的,例如使用 as? NSDictionary 而不是 as Dictionary


0

NSJSONSerialization.JSONObjectWithData 返回一个隐式解包的可选值,这意味着返回值可能为 nil。在无效的 JSON 情况下,将返回一个 nil 可选类型。因此,你的 var json 也必须是可选类型,因为它可能为 nil。此外,如果 var json 是可选类型,则必须通过在 as 旁边添加 ? 将其向下转换为可选类型。这是最终结果。

var json: NSDictionary? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as? NSDictionary

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接