为什么使用隐式解包或强制解包让某个阶段的应用程序崩溃无益?

时间:2018-06-15 04:31:26

标签: swift optional xctest unwrap forced-unwrapping

我的观点是在某些地方我们知道变量根本不会有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。但这不是重点。

我的问题是,我是否正确,在某些情况下,例如我给出的例子,让它展开展开/隐式展开是有益的。

1 个答案:

答案 0 :(得分:4)

不确定。有任何许多正确使用力展开的地方,只有在发展的早期才发生崩溃,因为已经犯了错误,一旦修复,碰撞再也不会发生。

一个常见的例子是从资源包中访问图像。一行如:

let imagePath = Bundle.main.path(forResource: "image", ofType: "png")!
如果开发人员忘记正确定位image.png

应该在早期开发中崩溃。一旦正确定位,该线路就不会崩溃,因此没有理由处理可选路径。

其他常见的例子是出口。它们通常是隐式展开的,因为当它们在视图控制器的代码中使用时,它们将被附加。碰撞可能意味着插座没有正确连接。它得到修复,不再担心。无需处理警卫或其他可选的检查。

最后一个例子(还有更多可能性)。从表视图中出列单元格时,将生成的单元格强制转换为自定义单元格类型。不需要看守。我总是在这里看到代码,如果转换失败,使用带as?的后卫会抛出致命错误。只是强制投射。使用较少的代码可以获得相同的崩溃。一旦表格视图和故事板正确,强制转换就不会失败。

话虽如此,较新的Swift开发人员应该暂时避开键盘上的!字符。知道何时安全使用它是一项学到的技能。

如果潜在的崩溃完全在开发人员的控制之下,并且崩溃只会因为开发人员犯了错误而发生,那么使用!可能是合适的。

如果潜在的崩溃可能是由意外数据(JSON解析,用户输入等)引起的,那么就不要使用!。在这些情况下防守代码。

tl; dr - 是的,有很多情况下强制解包,强制转换和隐式解包变量是正确的选择。