所以我知道'!'之间的区别和'?',我只是想知道在调用可选变量的方法时使用它们的最佳方法是什么
var bar: Bar? = nil
bar?.doSomething() // this will be valid, but wouldn't call doSomething
bar!.doSomething() // Given error: EXC_BAD_INSTRUCTIONS (Obviously)
但是当'bar'不是nil时,这两个方法调用都是有效的。
bar = Bar()
bar?.doSomething() // Valid
bar!.doSomething() // Valid
所以我的问题是,调用可选变量方法的最佳方法是什么,我个人使用:
if bar != nil {
bar!.doSomething()
}
还是吧?.doSomething()做同样的事情?
答案 0 :(得分:24)
我认为避免使用bar?.doSomething()
并始终使用if let bar = bar { ... }
是不好的建议。
主要有两个原因:
首先,bar?.doSomething()
更简洁。如果你在条件表达式中只用一个语句编写if let
,那么你可能会问自己是否不想将这些代码放在一行中使用较短的版本。
虽然这是完全合法的代码..
if let thing = thing {
thing.bar()
}
..以下是合法的,只是短得多......
thing?.bar()
其次,更重要的是这个问题的核心,它们不一样! if let
是一个综合测试,可选展开和分配,bar?
执行名为可选链接的内容。
后者在许多情况下非常有用,可以让你编写更好的代码。例如:
它可以用来替换它..
var imageGenerator: ImageGenerator?
if let generator = imageGenerator {
myView.image = generator.generateImage()
} else {
myView.image = nil
}
..只需:
myView.image = self.imageGenerator?.generateImage()
原因是因为可选链接在链中遇到nil
后立即返回nil
。由于UIImageView
有一个image: UIImage?
,因此它的值为零。即使它来自ImageGenerator?
与 Nil Coalescing Operator ??
结合使用时更有用。
现在你可以改变这段代码..
var imageGenerator: ImageGenerator?
if let generator = imageGenerator {
myView.image = generator.generateImage()
} else {
myView.image = DefaultImage
}
..进入..
myView.image = generator?.makeImageGenerator() ?? DefaultImage
..这样更简洁。
因为可选链接适用于 Chains ..您甚至可以执行以下操作:
myView.image = delegate?.makeImageGenerator()?.generateImage() ?? DefaultImage
哪个会变成......
if let delegate = delegate {
if let generator = delegate.generatorForImage() {
if let image = generator.generateImage() {
myView.image = image
} else {
myView.image = DefaultImage
}
} else {
myView.image = DefaultImage
}
} else {
myView.image = DefaultImage
}
..如果你没有使用可选链接和 Nil Coalescing Operator 。
(是的myView.image = DefaultImage
只能在最后有条件地完成,但这意味着您仍然需要引入额外的代码来检查它是否已设置。它不会短得多。)
有两个新技巧: - )
答案 1 :(得分:4)
当你这样做时
bar?.doSomething()
这意味着,如果bar为nil,则不会继续执行doSomething方法,但返回nil。如果要处理nil的情况,则应检查对象是否包含nil。你也可以这样做,通过可选的绑定:
if let unwrappedBar = bar {
unwrappedBar.doSomething()
} else {
doSomeOtherThing() // In case it's nil
}
它使if let语句中的值可用作一个名为unwrappedBar的临时常量(如果你愿意,可以给它任何其他名称),如果它不是nil。
您还可以使用更短的语法和可选的链接和合并运算符:
bar?.doSomething() ?? doSomeOtherThing()
以下是有关访问可选值的不同方法的更多信息:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID330
答案 2 :(得分:2)
bar?.doSomething()
是调用可选变量方法的最佳方法。如果bar不是零,它只会调用一些东西。您编写的代码最少,这与实施if let
检查
if let bar = bar {
bar.doSomething()
}