强制展开或使用可选链接来设置 属性

Force unwrap or use optional chaining to set property

给定一个具有已设置属性的可选变量 pinImageView: UIImageView?,我不确定设置 属性 的首选方式。例如:

if let image = UIImage(named: "Pin") {
    pinImageView = UIImageView(image: image)
    pinImageView?.restorationIdentifier = "pin"
}

if let image = UIImage(named: "Pin") {
    pinImageView = UIImageView(image: image)
    pinImageView!.restorationIdentifier = "pin"
}

which way is preferred

人们普遍认为你应该避免 ! (force unwrapping) 这只是在乞求崩溃,所以应该避免这种用法:

if let image = UIImage(named: "Pin") {
    pinImageView = UIImageView(image: image)
    pinImageView!.restorationIdentifier = "pin"
}

在这种情况下,由于您刚刚分配了 pinImageView,强制展开它是安全的,但是它仍然向您或任何其他阅读者发出危险信号你的代码在未来。 "Ugh, they're using force unwrap here. Could that crash? Well, could pinImageView be nil? No, it was just assigned in the previous line, so it's OK." 为什么要让自己和他人经历这个思考过程;尽可能避免 !

这个用法:

if let image = UIImage(named: "Pin") {
    pinImageView = UIImageView(image: image)
    pinImageView?.restorationIdentifier = "pin"
}

更安全,因为它使用 可选链接 解包 pinImageView 并避免了 崩溃运算符 !,但它仍然展开一个可选变量。

第三种选择:

imageView 是可选的原因是您已将其分配给可选变量。相反,如果您在配置对象时使用 let 常量来保存对象,则可以避免用解包代码填充代码:

if let image = UIImage(named: "Pin") {
    let imageView = UIImageView(image: image)
    imageView.restorationIdentifier = "pin"
    pinImageView = imageView
}

当您为对象分配许多属性时,此方法很有效,因为您可以避免许多展开运算符。

不用担心额外的代码行。编译器会优化它。代码的可读性和清晰度。

我们的团队中有一条代码 style/review 规则,大致如下:“禁止 使用 ! 运算符,但不要评论说明其安全性”。

因为!破坏了 Swift 中 nil-safety 的所有优点,随意使用它会导致崩溃并将语言拖回 C/C++/Java/C#/Javascript/etc NullPointerException 地狱.

所以在你的情况下

pinImageView?.restorationIdentifier = "pin"

选项肯定是首选。