Swift:隐式解包变量有效,但不强制将其转换为相同类型。为什么?

问题描述 投票:-3回答:3

我有一个MyCell,是一种UIView。我可以创建如下。

private let myCell: MyCell! = MyCell.createFromNib()
myCell.callingFunction()

这表明myCell不是nil。但是,如果我想明确地将其转换为如下,并重新启动相同的代码(这意味着myCell不会是nil,因为相同的代码以前不是nil)

private let myCell = MyCell.createFromNib() as! MyCell
myCell.callingFunction()

它会因错误而崩溃

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

我认为这也应该有效。这两者有什么不同?

仅供参考createFromNib功能声明如下

class func createFromNib<T: UIView>() -> T?

仅供参考,我是iOS和Swift的新手

swift
3个回答
1
投票

实际上(不出意料地)隐蔽地展开的选项是引人注目的选项! IUO带来的唯一优势是您不需要编写!(强制解包)运算符,编译器会为您执行此操作。

这意味着nil值是IUO的可接受值。这就是为什么MyCell.createFromNib()被允许被分配给myCell的原因,即使在某些条件下函数可能返回nil。

另一方面,MyCell.createFromNib() as! MyCell在赋值之前被计算,并且as!总是导致非可选值,除非应用于无法转换的值(nil或其他层次结构)。因此,失败的分配不是,强制转换操作会触发致命错误。

MyCell.createFromNib() as? MyCell也会工作得很好,不同的是,这可能会引入一个无声的错误而不是崩溃。现在,由您来决定这是否优先。我会去掉半崩溃的解决方案:Debug崩溃,Release上的静默失败。这样在QA阶段可能会遇到潜在问题,但是,如果没有捕获它们,它们不会使生产应用程序崩溃。

let cell = MyCell.createFromNib()
assert(cell != nil, "Oops, something bad happened, please call the Avengers")
myCell = cell as? MyCell

3
投票
  • 在第一个示例中,您将变量声明为隐式展开的可选项,但您只需将createFromNib的 - 显然是可选的 - 结果写入此变量,该变量可能是nil
  • 在第二个例子中,您在投射时阅读了createFromNib的结果。如果它是nil它崩溃了。

2
投票

private let myCell: MyCell!

在这里,myCell可以包含nil或MyCell类型的值因此,为此分配nil值是完全正常的。 (但是,如果在值为nil时使用它,则会出错。)


private let myCell = MyCell.createFromNib() as! MyCell

在这里,您正在尝试将nil转换为MyCell类型,这绝对是一个错误。


注意:我认为MyCell.createFromNib()在两种情况下都会在代码中返回nil。

© www.soinside.com 2019 - 2024. All rights reserved.