我的观点是在某些地方我们知道变量根本不会有nil,但由于某种原因我们无法在类的init函数中实例化它,所以我们必须使它成为可选项。
我也知道我们可以使用可选的绑定或防护技术来轻松摆脱它。
但是,由于隐含的展开/强制展开,让应用程序因某些非常愚蠢的错误而崩溃,对于我认为处于开发阶段的开发人员来说是有益的。。
我的例子是:
class TopStoriesViewModelTests: XCTestCase {
var viewModel: TopStoriesViewModel!
override func setUp() {
super.setUp()
viewModel = TopStoriesViewModel(interactor: MockTopStoriesInteractor())
}
func testArticleDidVisited() {
viewModel.visited = xxxxxx
}
}
在这种情况下,我可以TopStoriesViewModel
一个?
然后保护它,或者如果在每个测试用例中都让它,但我觉得没有必要。我知道我也可以使用viewModel?.xxx
。但这不是重点。
我的问题是,我是否正确,在某些情况下,例如我给出的例子,让它展开展开/隐式展开是有益的。
答案 0 :(得分:4)
不确定。有任何许多正确使用力展开的地方,只有在发展的早期才发生崩溃,因为已经犯了错误,一旦修复,碰撞再也不会发生。
一个常见的例子是从资源包中访问图像。一行如:
let imagePath = Bundle.main.path(forResource: "image", ofType: "png")!
如果开发人员忘记正确定位image.png
,应该在早期开发中崩溃。一旦正确定位,该线路就不会崩溃,因此没有理由处理可选路径。
其他常见的例子是出口。它们通常是隐式展开的,因为当它们在视图控制器的代码中使用时,它们将被附加。碰撞可能意味着插座没有正确连接。它得到修复,不再担心。无需处理警卫或其他可选的检查。
最后一个例子(还有更多可能性)。从表视图中出列单元格时,将生成的单元格强制转换为自定义单元格类型。不需要看守。我总是在这里看到代码,如果转换失败,使用带as?
的后卫会抛出致命错误。只是强制投射。使用较少的代码可以获得相同的崩溃。一旦表格视图和故事板正确,强制转换就不会失败。
话虽如此,较新的Swift开发人员应该暂时避开键盘上的!
字符。知道何时安全使用它是一项学到的技能。
如果潜在的崩溃完全在开发人员的控制之下,并且崩溃只会因为开发人员犯了错误而发生,那么使用!
可能是合适的。
如果潜在的崩溃可能是由意外数据(JSON解析,用户输入等)引起的,那么就不要使用!
。在这些情况下防守代码。
tl; dr - 是的,有很多情况下强制解包,强制转换和隐式解包变量是正确的选择。