何时使用未包装的可选值作为类型定义的一部分

When to use unwrapped optionals as part of a type definition

比方说,我们定义一个class

class C{
    var unwrapped : String!
    var nonOptional : String

    init(nonOptional:String){
        self.nonOptional = nonOptional
    }   
}

然后我们创建一个 C:

的实例
var c = C(nonOptional: "hola")

我看到的是这两个属性之间的主要区别是没有必要初始化未包装的 属性 并且您可以像这样进行比较:

if c.unwrapped == nil{
   // Do whatever
}

虽然非可选 属性 不允许您与 nil 进行比较。

关键是,在我看来,创建未包装的 属性 是不安全的,因为当您尝试访问具有 nil 值的未包装属性时,代码可能会生成更多运行时异常。然而,非可选值将使开发人员处理代码并初始化属性以避免这种情况。

那么谁能告诉我什么情况适合创建展开的属性?

您的方法是正确的,创建未包装的 属性 是不安全的 因为如果您的未包装值为 nil,您的应用程序将碰撞。为避免这种情况,您应该使用 if let 关闭而不是检查 == nil。例如

class C{
    var unwrapped : String?
    var nonOptional : String

    init(nonOptional:String){
        self.nonOptional = nonOptional
    }   
}

var c = C(nonOptional: "hola")

if let value = c.unwrapped {
     /// value is not nil here 
}

HERE 关于 optionals

的精彩演讲

有些情况下无法在初始化对象时设置变量,但您或多或少可以保证在使用它们之前设置属性。 IBOutlets 就是其中一个例子。它们在创建视图控制器之后设置,但在调用 viewDidLoad 之前设置。这就是为什么它们被标记为未包装的可选。

另一种情况是您希望将一些数据传递给对象。假设您有一个视图控制器,它正在呈现由呈现视图控制器传递的信息。视图控制器可能有一个 属性 var information: MyCustomObject! 因为你知道为了让视图控制器在屏幕上显示信息,必须设置这个 属性 ;但是,无法设置 属性 before/while 创建视图控制器。您通常会从 segue 实例化视图控制器,然后在 prepareForSegue: 中设置 属性.

上面的例子当然可以使用可选值,但是如果你知道设置了可选值,你可以像使用非可选值一样节省很多if let ...(理论上,一切都可以声明为可选的,但为什么你的所有检查都知道 属性 已设置?)。