如果一个函数返回一个隐式取消包装的可选函数,你会将它赋给显式可选函数吗?
例如,在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);
如果函数要返回不能为nil的值,为什么要将其赋给可选的?
发布于 2014-09-01 16:40:42
在这种特殊情况下,AnyObject!
的返回是SDK中的一个错误(从技术上讲,它只是一个地方,他们已经使用了自动Swiftifier,还没有手动修复它)。JSONObjectWithData
绝对可以返回nil
。从文档中:
基础返回值: data中
数据的基础对象,如果出现错误,返回值为空。
Chris将这个值从可能的崩溃中拯救出来,方法是将它移动到显式可选项,而不是实际上可能为ni的隐式值。
发布于 2014-09-01 16:47:58
只要您可以将Implicit Unwrapped Optional
更改为由api返回的Optional Type
,您就应该始终使用此方法,因为xcode将来的版本将尝试将其Implicit Optionals type
替换为explicit optional
,并且在beta 6和5中,此方法已开始使用,并且许多api已更改为使用explicit optional
type.The专家建议尽可能避免Implicit Unwrapped Optional
,因为每当使用automatically.While类型对Implicit Unwrapped Optional
进行解包装时,您都会遇到崩溃。您必须显式地解开该值,因此您可以通过放置if
条件或如果你真的确信它不会是空的,因为你可以在没有if
的情况下解开它(但你应该总是检查nil
大小写)。
JSONObjectWithData
可以返回nil
,因为你不知道evilData
中有什么,如果它不能在json
中转换,你会得到nil
值,如果你试图在代码中的其他地方使用jsonResponse
和implicit optional type
,而不是你的应用程序将在运行时崩溃。这就是为什么克里斯使用explicit optional
来注意这种情况,否则在使用jsonResponse
不会自动解包到nil的情况下,这可能会导致crashes.If,你可以自己用<代码>D20或<代码>D21解包代码,你可以避免崩溃并显示一些有意义的完整消息。
发布于 2014-09-01 16:49:39
隐式展开的可选选项仍然是可选的,尽管它被保证保持一个值。
将隐式展开的可选赋值给正常的可选是合法的。
因此,如果您的应用程序中有一个线性逻辑,其中您声明了一个可选变量,然后使用隐式展开的可选对其进行初始化,则最好使用非可选的。
但在某些情况下,您定义了一个可选变量(假设在函数的开头),然后根据条件、流、if等,可以从不同的函数中为其赋值-如果其中至少有一个函数可以返回普通的可选变量,那么您必须将该变量声明为可选变量。
但在这种情况下,即使用于为可选/非可选变量赋值的所有函数总是返回非可选或(至少其中一个)隐式展开的可选,最好还是使用可选声明,因为将来可能会有一个新的代码分支返回正常的可选。
最后,非常有趣的是,这似乎工作得很好,
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所说的:
如果在未包含值的情况下尝试访问隐式展开的可选对象,则会触发运行时错误。结果与在不包含值的normal optional后面放置感叹号完全相同。
这意味着:赋值nil
是可以的,但只要它被访问(即赋值给另一个变量,在表达式中使用,等等)它将触发错误
https://stackoverflow.com/questions/25609822
复制相似问题