强制解包选项和隐式解包选项之间的区别

Difference between Force Unwrapping Optionals and Implicitly Unwrapped Optionals

起初我对强制展开和隐式展开感到非常困惑。现在,以下的理解来自于我的自学:

没有 操作可用于隐式解包,但有一种叫做隐式解包选项的东西。隐式展开的 Optional 和普通的 Optional 都是 Optional,区别在于访问隐式展开的 Optional 时,您可以自信地知道引擎盖下有一个有效值并可以使用。 Normal Optionals 需要 if let bindingforced unwrapping (!) action 来访问可选变量背后的可能值.

摘要

强制解包 是对普通可选对象执行的操作

Implicitly unwrapped OptionalsOptionals,通常用于class初始化并在使用时传递不带感叹号的值。

问题:

我说的对吗?如果我的理解不准确,还请指正。

谢谢

隐式展开的可选值是幕后的普通可选值,但也可以像非可选值一样使用,所以是的,你 正确

但是,如果您将一个值声明为隐式解包,则相当于在每次使用时强制解包。

对于隐式解包选项,这样做有 4 个主要原因。

1: 初始化期间无法定义的常量

2:与 Objective-C API

互动

3:当您的应用无法从变量中恢复时 nil

4:NSObject 初始化程序

首先让我们定义一个Optional

可选值是某种类型(IntStringUIColor、...)的容器,它可以包含值 (1, "Hello world", .greenColor(), ...) 或 nil.

let anOptionalInt: Int? = 1
let anotherOptionalInt: Int? = nil

当我们在 Swift 中看到一个 Optional 值时,我们认为:

Ok this could contain the actual value or nil

强制展开

这是提取 Optional 中包含的值的操作。 此操作很危险,因为您是在告诉编译器:我确定此可选值确实包含真实值,提取它!

let anOptionalInt: Int? = 1
let anInt: Int = anOptionalInt!

现在 anInt 包含值 1。

如果我们对恰好包含 nil 的 Optional 值执行强制展开,我们会得到 fatalError,应用程序确实会崩溃并且无法恢复它。

let anotherOptionalInt: Int? = nil
let anotherInt = anotherOptionalInt!

fatal error: unexpectedly found nil while unwrapping an Optional value

隐式展开的可选值

当我们定义一个隐式展开的可选时,我们定义了一个容器,它会在我们每次读取它时自动执行强制展开。

var text: String! = "Hello"

如果现在我们阅读text

let name = text

我们没有得到一个可选的 String,而是一个普通的 String,因为 text 自动解包了它的内容。

但是文本仍然是可选的,因此我们可以在其中放置一个 nil

text = nil

但是我们一读到它(它包含 nil),我们就得到一个致命错误,因为我们正在展开一个包含 nil

的可选
let anotherName = text

fatal error: unexpectedly found nil while unwrapping an Optional value

我会说不,你在做一个错误的区分:

  • 前半句是对的;展开当然是你对 Optionals 做的事情,强制展开是一种方式(一种不安全的方式)。

  • 但是关于什么是隐式解包的 Optional 是:它是一种标记 Optional 类型的方法,以便你完成强制解包(如果你在不能使用它的地方使用了 Optional,但如果它被解开是可以使用的)。

隐式展开 当您像这样定义其类型时,您将 Optional 定义为隐式解包。

让 unwrappedString: String!

此技术允许您告诉编译器自动解包该值,就好像它根本不是可选的一样。 类似于类型?这是 Optional, Type! 的语法糖!等同于 ImplicitlyUnwrappedOptional。 隐式展开可选的一个常见示例是视图控制器如何定义其 IBOutlets:

@IBOutlet var displayLabel:UILabel! @IBOutlet var actionButton: UIButton!

将插座定义为隐式解包可选是有意义的,因为它们将由 Interface Builder 实例化。总是在视图控制器中解开每个视图出口是很麻烦的。 由于它们隐式展开的性质,如果您忘记将插座连接到它,Interface Builder 查看 运行 应用程序,当您尝试在视图控制器中访问它时,您将收到 运行 时间错误。