将隐式展开的可选项分配给显式可选项

时间:2014-09-01 16:24:06

标签: swift optional

如果函数返回一个隐式解包的可选项,你会将它分配给一个显式的可选项吗?

例如,在Chris Adamson的blog post中,他首先列出了一个返回隐式展开的函数,然后他将函数的返回值赋给显式可选。

class func JSONObjectWithData(_ data: NSData!,
                      options opt: NSJSONReadingOptions,
                        error error: NSErrorPointer) -> AnyObject!

let jsonResponse : AnyObject? =
NSJSONSerialization.JSONObjectWithData(evilData,
    options: NSJSONReadingOptions(0),
    error: &parseError);

如果函数要返回一些不能为零的函数,为什么要将它赋给一个可选的?

3 个答案:

答案 0 :(得分:3)

在这种特殊情况下,AnyObject!的返回是SDK中的一个错误(从技术上讲,它只是他们使用自动Swiftifier和避风港的地方 - 固定它)。 JSONObjectWithData绝对可以返回nil。来自文档:

  

返回值:   数据中JSON数据的Foundation对象,如果发生错误,则为nil。

克里斯正在将这个值从可能的崩溃中拯救出来,将它移动到一个明确的可选项而不是一个实际可能是ni的隐式可选项。

答案 1 :(得分:0)

每当您将Implicit Unwrapped Optional更改为api返回的Optional Type时,您应始终使用此方法,因为xcode将来的版本会尝试将其api从Implicit Optionals type替换为{{1}在beta 6和5中,这种方法已经开始,并且许多api已被更改为使用explicit optional类型。专家建议是尽可能避免使用explicit optional,因为每当{{{}} {}时都会崩溃1}}是自动解包的。使用Implicit Unwrapped Optional类型时你必须显式打开这个值,这样你就可以通过设置一个nil条件,或者如果你真的确定它不会比你可以解开它没有optional(explicit)(但您应该始终检查if案例)。

if可以返回nil,因为您不知道JSONObjectWithData中的内容,如果无法转换nil,您将获得evilData如果你尝试在代码中的其他地方使用jsonnil,那么你的应用程序会在运行时崩溃。这就是为什么克里斯用jsonResponse来照顾这个案例而在其他地方implicit optional type的使用不会自动解包到nil,这可能导致崩溃。如果您使用explicit optionaljsonResponse自行解包代码,则可以避免崩溃并显示一些含义完整的消息。

答案 2 :(得分:-1)

隐式展开的可选项仍然是可选的,但它保证保留一个值。

将隐式解包的可选项分配给普通的可选项是合法的。

因此,如果您的应用程序中有一个线性逻辑,您声明了一个可选变量,然后使用隐式展开的可选项对其进行初始化,那么最好使用非可选项。

但是在某些情况下你定义了一个可选变量(让我们在函数的开头说),然后根据条件,流程,如果等等,它可以从不同的函数中分配一个值 - 如果其中至少有一个可以返回普通的可选项,则必须将该变量声明为可选项。

但是在这种情况下,即使用于为可选/非可选变量赋值的所有函数总是返回非可选项或(至少其中一项)隐式展开的可选项,它始终是最好坚持使用可选的声明,因为将来你可能会有一个新的代码分支返回一个普通的可选声明。

最后,非常有趣的是,这似乎工作正常

let x: Int! = nil

虽然我不得不承认我希望它抛出运行时异常。知道这一点,我想从现在开始,当函数声称返回一个隐式解包时,我总是会使用一个可选项。

更多测试:

func test() -> Int! {
    return nil
}

let q1: Int? = test() // it works, q1 = nil (expected)
let q2: Int! = test() // it works, q2 = nil (unexpected)
let q3: Int = test() // runtime exception (expected)

更新:这是documentation所说的内容:

  

如果在不包含值时尝试访问隐式展开的可选项,则会触发运行时错误。结果与在不包含值的普通可选项之后放置感叹号完全相同。

这意味着:分配nil是可以的,但是只要它被访问(即分配给另一个变量,在表达式中使用等),它就会触发错误