Swift 在可空性可用性之前使用隐式解包可选



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

"...在 Swift 中,可选和 非可选引用,例如 NSView vs. NSView?,而 Objective-C 将这两种类型表示为 NSView *。因为雨燕 编译器无法确定特定的 NSView * 是可选的还是 不是,该类型作为隐式解包引入 Swift 可选,NSView!

这是否意味着以前在 Swift 中将 Objective-C 方法声明为返回隐式解包的可选方法

时,它实际上可能会崩溃(因为使用隐式解包的可选声明的某些方法可能会返回 nil)?还是Apple确保只有那些绝对不返回nil的Objective-C方法被声明为隐式解包的可选方法?

苹果的框架并没有什么特别之处。 一开始,你在 Swift 中使用 Objective-C 的所有内容(每个对象)都是隐式解包的可选。 这是因为 Objective-C 中的每个指针都可能返回 nil

事实上,即使在 Objective-C 可空性注释的时代,注释为 nonnull 的方法也并非完全不可能返回nil。 Objective-C 不强制实施可空性规则,它只是提供了一种注释代码的方法,以便从 Swift 使用代码更安全。 就苹果的框架而言,我敢打赌,你不会有这个问题。 或者,如果您这样做,下一个版本的Xcode将修复它。

但同样,来自Objective-C库和框架的隐式解包的可选没有什么特别之处。 隐式解包的可选告诉你的唯一事情是框架作者还没有努力批注他们的库(你不能在带注释的库中留下隐式解包的可选)。 是的,这些隐式解包的选项可以nil,它们可能会使您的应用程序崩溃。

在Apple的情况下,如果出于某种原因,您在不同的项目中使用Xcode 7和Xcode 6,如果您采用Xcode 7的更新注释声明为非可选的内容,那么假设Xcode 6中隐式解包的可选版本永远不会nil可能会奏效。 但是,如果你在 Xcode 7 中采用可选的东西,假设 Xcode 6 中隐式解包的版本永远不会被nil

那么你的应用程序很有可能崩溃。

最终,在 Swift 中,我们对隐式解包的 Optional 的使用应该很少而且相距甚远。 隐式解包的可选的主要用途应主要用于在返回类初始化之前无法设置的类属性(例如,在视图控制器中@IBOutlets)。 否则,它们很容易成为Stack Overflow上许多"意外发现的零"问题的来源。


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

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

其次,这就是语言设计互操作的方式。 任何没有添加可空性注释的 Objective-C 文件都将被视为 Swift 中所有内容都是隐式解包的可选文件。

第三,隐式可选的原因在于它减少了 Optional 所需的 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的可能性做出正确的假设。

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

不。隐式解包的可选是可选的 - 这意味着nil是完全可接受的值。将隐式解包的 Optional 作为 nil 不会崩溃,只有当您尝试在没有可选绑定或可选链接的情况下直接访问其上的成员时,它才会崩溃。

还是苹果只确保那些Objective-C 绝对不返回 nil 的方法被隐式声明为隐式 解开包装可选?

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

最新更新