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

时间:2015-06-17 01:41:11

标签: swift objective-c-nullability

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

  

“...在Swift中,可选和。之间有很大的区别   非可选引用,例如NSView与NSView ?,而Objective-C   将这两种类型都表示为NSView *。因为斯威夫特   编译器无法确定特定的NSView *是可选的还是   不是,这个类型被带入Swift作为一个隐含的解包   可选,NSView!“

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

2 个答案:

答案 0 :(得分:6)

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

事实上,即使在Objective-C可空性注释的时代,注释为nonnull的方法也不可能完全返回nil。 Objective-C没有强制执行可空性规则,它只是提供了一种注释代码的方法,以便 从Swift中使用起来更安全。在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等语句的大量冗长,而不能保证变量实际上是non-nil。造成这种情况的大部分原因可能是因为您认为大多数这些方法实际上永远不会返回nil

第四,如果你知道哪些人有机会成为nil而哪些人没有,你实际上可以继续编写你的Swift代码,以便处理对目标的哪种方式做出假设-C代码将被注释。

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

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

示例:

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

override func someOtherFunc(implicitVal: String!) -> String {
    return implicitVal
}

如果我们将它们全部视为选项,那么第二个例子将不起作用

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

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

答案 1 :(得分:1)

  

在将Objective-C方法声明为时,这是否意味着   在Swift中隐式返回unwrapped可选,它实际上可能会崩溃   (因为一些声明的方法是使用隐式解包的可选方法   可能会返回nil)?

没有。隐式展开的可选项是可选的 - 这意味着nil是一个完全可接受的值。有一个隐式解包的可选项nil不会崩溃,只有当你尝试直接访问它上面的成员而没有可选绑定或可选链接时它会崩溃。

  

或Apple确定只有那些Objective-C   绝对不返回nil的方法被隐式声明   解包可选?

如果知道不返回nil,那么Apple在审核后会将其声明为非可选项,不是一个隐式解包的可选项。只有在不知道它是否可以返回nil时,它才会返回隐式解包的可选项。