强制解包选项和隐式解包选项之间的区别
Difference between Force Unwrapping Optionals and Implicitly Unwrapped Optionals
起初我对强制展开和隐式展开感到非常困惑。现在,以下的理解来自于我的自学:
没有 操作可用于隐式解包,但有一种叫做隐式解包选项的东西。隐式展开的 Optional 和普通的 Optional 都是 Optional,区别在于访问隐式展开的 Optional 时,您可以自信地知道引擎盖下有一个有效值并可以使用。 Normal Optionals 需要 if let
binding 或 forced unwrapping (!
) action 来访问可选变量背后的可能值.
摘要:
强制解包 是对普通可选对象执行的操作。
Implicitly unwrapped Optionals是Optionals,通常用于class初始化并在使用时传递不带感叹号的值。
问题:
我说的对吗?如果我的理解不准确,还请指正。
谢谢
隐式展开的可选值是幕后的普通可选值,但也可以像非可选值一样使用,所以是的,你 正确。
但是,如果您将一个值声明为隐式解包,则相当于在每次使用时强制解包。
对于隐式解包选项,这样做有 4 个主要原因。
1: 初始化期间无法定义的常量
2:与 Objective-C API
互动
3:当您的应用无法从变量中恢复时 nil
4:NSObject
初始化程序
首先让我们定义一个Optional
可选值是某种类型(Int
、String
、UIColor
、...)的容器,它可以包含值 (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 查看 运行 应用程序,当您尝试在视图控制器中访问它时,您将收到 运行 时间错误。
起初我对强制展开和隐式展开感到非常困惑。现在,以下的理解来自于我的自学:
没有 操作可用于隐式解包,但有一种叫做隐式解包选项的东西。隐式展开的 Optional 和普通的 Optional 都是 Optional,区别在于访问隐式展开的 Optional 时,您可以自信地知道引擎盖下有一个有效值并可以使用。 Normal Optionals 需要 if let
binding 或 forced unwrapping (!
) action 来访问可选变量背后的可能值.
摘要:
强制解包 是对普通可选对象执行的操作。
Implicitly unwrapped Optionals是Optionals,通常用于class初始化并在使用时传递不带感叹号的值。
问题:
我说的对吗?如果我的理解不准确,还请指正。
谢谢
隐式展开的可选值是幕后的普通可选值,但也可以像非可选值一样使用,所以是的,你 正确。
但是,如果您将一个值声明为隐式解包,则相当于在每次使用时强制解包。
对于隐式解包选项,这样做有 4 个主要原因。
1: 初始化期间无法定义的常量
2:与 Objective-C API
互动3:当您的应用无法从变量中恢复时 nil
4:NSObject
初始化程序
首先让我们定义一个Optional
可选值是某种类型(Int
、String
、UIColor
、...)的容器,它可以包含值 (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 查看 运行 应用程序,当您尝试在视图控制器中访问它时,您将收到 运行 时间错误。