Swift在可空性的可用性之前使用Implicitly Unwrapped Optional

Boo*_*oon 3 swift objective-c-nullability

在Apple关于可空性的博客中,他们提到了这一点:

"...在Swift中,可选和非可选引用之间存在很大的区别,例如NSView与NSView?,而Objective-C将这两种类型都表示为NSView*.因为Swift编译器无法确定是否存在特别是NSView*是否可选,该类型作为一个隐式解包的可选NSView进入Swift!"

这是否意味着之前在声明Objective-C方法为在Swift中隐式解包可选的方法时,它实际上可能会崩溃(因为使用隐式解包的可选项声明的某些方法可能会返回nil)?或者,Apple是否确保只有那些绝对不返回nil的Objective-C方法被声明为隐式解包的可选项?

nhg*_*rif 6

Apple的框架并不特别.在开始时,您在Swift中使用Objective-C的所有内容(每个对象)都是一个隐式解包的可选项.那是因为Objective-C中的每个指针都可能返回nil.

实际上,即使在Objective-C可空性注释的时代,注释的方法也不是完全不可能nonnull返回的nil.Objective-C的不强制为空性规则,它只是提供了注解你的代码,以便它的手段应该是更安全的,从斯威夫特使用.在Apple的框架中,我敢打赌,这是一个非常安全的赌注,你不会有这个问题.或者,如果你这样做,Xcode的下一个版本将修复它.

但同样,来自Objective-C库和框架的隐式解包选项没有什么特别之处.隐式解包的可选项告诉您的唯一事情是框架作者尚未努力注释其库(您不能在已注释的库中隐式包含未包装的选项). 是的,这些隐式解包的选项可能会nil导致应用程序崩溃.

在Apple的情况下,如果由于某种原因,你在不同的项目中使用Xcode 7和Xcode 6,如果你采取了Xcode 7的更新注释声明为非可选的东西,那么假设在Xcode中隐式解包的可选版本6将永远不会nil成功.但是如果你在Xcode 7中采取一些可选的东西,假设从Xcode 6中隐式展开的版本将永远不会有nil可能崩溃你的应用程序.

最终,在Swift中,我们对隐式展开的选项的使用应该是少之又少.隐式展开的选项的主要用途应该主要保留给在返回类初始化之前无法设置的类属性(例如,@IBOutlets在视图控制器中).否则,它们很容易成为Stack Overflow上众多"意外发现的零"问题的来源.


对于"为什么要返回隐式解包的可选而不是可选?"的问题,有几点......

首先,这是一个语言设计问题.我不是在Objective-C或Swift语言设计团队中,这些团队中的任何人都不太可能会停下来回答这个问题......

其次,这就是语言的互操作性.没有添加任何可空性注释的任何Objective-C文件都将被视为在Swift中一切都是隐式解包的可选项.

第三,隐式选项的原因是它减少了if let可选需要的etc语句的大量冗长,而不能保证变量实际上是这样non-nil.造成这种情况的大部分原因可能是因为您认为大多数这些方法实际上永远不会返回nil.

第四,如果您知道哪些机会有机会哪些机会nil不存在,那么您实际上可以继续编写Swift代码,以便处理对Objective-C代码将被注释的方式的假设.

例如,使用隐式展开的可选项,当然,您可以将其视为非可选项,并删除与展开相关的一些次要详细程度.

另外,如果您认为可能存在隐式展开的可选项,则nil所有可选的展开内容仍然可以使用它.

例:

override func someFunc(implicitVal: String!) -> String {
    return implicitVal ?? "It was nil!"
}

override func someOtherFunc(implicitVal: String!) -> String {
    return implicitVal
}
Run Code Online (Sandbox Code Playgroud)

如果我们将它们全部视为可选项,则第二个示例将不起作用

如果我们将它们假设为非选项,那么第一个例子将不起作用.

隐式解包的选项允许Swift开发人员自由地将它们视为对价值可能性做出正确假设nil.