3

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

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

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

4

2 回答 2

6

Apple 的框架并没有什么特别之处。一开始,您在 Swift 中从 Objective-C 中使用的所有内容(每个对象)都是隐式展开的可选项。那是因为 Objective-C 中的每个指针都可能返回nil.

事实上,即使在 Objective-C 可空性注解的时代,注解为 as 的方法也不是完全不可能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可选需要的 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
}

如果我们假设它们都是可选的,那么第二个例子就行不通了

如果我们假设它们是非可选的,那么第一个例子就行不通了。

隐式展开的可选项允许 Swift 开发人员自由地对待它们,如果他们对值的可能性做出了正确的假设nil

于 2015-06-17T12:22:19.070 回答
1

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

不,一个隐式展开的可选项是一个可选项——这意味着它nil是一个完全可以接受的值。具有隐式展开的可选 asnil不会崩溃,只有当您尝试直接访问其上的成员而不使用可选绑定或可选链接时,它才会崩溃。

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

如果已知它不返回nil,那么 Apple 在审核后会将其声明为非可选,而不是隐式展开的可选。只有当它不知道它是否可以返回nil时,它才会返回隐式展开的可选。

于 2015-06-17T21:49:29.930 回答