0

我有这个:

let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

        dispatch_async(queue, {
            if let data = NSURLConnection.sendSynchronousRequest(self.buildRequestForVenueLocation(location, identifier), returningResponse: &response, error: &error) {
                let responseDictionary: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: .allZeros, error:&error) ?? error?.localizedDescription
                dispatch_async(dispatch_get_main_queue(), {
                    completion(venues: responseDictionary, error: error)
                })
            } else {
                println("There was a problem with the request...")
            }
        })

我的问题特别是关于这条线:

let responseDictionary: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: .allZeros, error:&error) ?? error?.localizedDescription

这是正确的用法nil coalescing吗?

根据Apple的文档,这是等效的:

a != nil ? a! : b

如果 a 为 nil,则返回 b,但如果 b 是可选类型,这有关系吗?

编辑

如果有人想知道,这就是我调用该函数时的样子:

v.performVenueLocationRequest(l.location, identifier: "4d4b7105d754a06374d81259") {
        if let result = $0 as? [String: AnyObject] ?? $1 {
            println(result)
        }
    }
4

2 回答 2

1

这取决于你所说的“物质”是什么意思。它会起作用的。它可能不是你想要的——如果b是可选的,那么结果也是可选的,即即使a有一个值,它仍然不会被解包:

let a: Int? = 2
let b: Int? = 3
let c = i ?? j
// c is {Some 2}

相对:

let i: Int? = nil
let j: Int? = 3
let k = i ?? j
// k is {Some 3}

查看这篇文章可能比你想知道的更多,但简而言之:无论运行时和的值是什么,结果都必须在编译时固定为特定a类型b。由于b是可选的,a!因此被隐式包装在可选中以使两种类型兼容。这么说吧——如果结果不是可选的,并且bnil,结果会是什么?

请记住,您可以链接??,因此您可以在末尾放置第三个值,该值不是可选的,这会使结果成为非可选的。

于 2015-01-04T16:09:19.697 回答
0

这是零合并。

如果 b 不是可选的:
a ?? b如果 a 不是 nil,将返回未包装的 a。如果 a 为 nil,它将返回 b。

如果 b 是非可选的:
a ?? b如果 a 不为零,则返回 a。如果 a 为 nil,它将返回 b。

此代码将起作用。但是由于无论如何您都是单独捕获错误,我建议将 responseDictionary 保留为 nil 而不是将其分配给error.localDescription(如果失败)。这只是更好的设计。如下所示。

let responseDictionary: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: .allZeros, error:&error)
于 2015-01-04T16:21:51.957 回答