为什么使用隐式解包或强制解包让应用程序在某个阶段崩溃没有好处?

Ton*_*Lin 1 optional xctest swift forced-unwrapping unwrap

我的观点是在某些地方我们知道变量根本不会有 nil 但由于某种原因我们不能在类的 init 函数中实例化它所以我们必须使它成为可选的。

我也知道我们可以使用可选的绑定或保护技术来轻松摆脱它。

但是在我看来,让应用程序因为隐式解包/强制解包而在一些非常愚蠢的错误中崩溃对于开发阶段的开发人员来说是有益的

我的例子是:

class TopStoriesViewModelTests: XCTestCase {
    var viewModel: TopStoriesViewModel!

    override func setUp() {
        super.setUp()
        viewModel = TopStoriesViewModel(interactor: MockTopStoriesInteractor())
    }

    func testArticleDidVisited() {
        viewModel.visited = xxxxxx
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我可以制作TopStoriesViewModel一个?then 保护它,或者在每个测试用例中都使用它,但我觉得没有必要。我知道我也可以使用viewModel?.xxx。但这不是重点。

我的问题是,在某些情况下,例如我给出的示例,强制解包/隐式解包是有益的,我是否正确。

rma*_*ddy 5

当然。force-unwrapping 有很多正确的用法,只有在开发早期才会发生崩溃,因为已经犯了错误,一旦修复,崩溃就不会再发生。

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

let imagePath = Bundle.main.path(forResource: "image", ofType: "png")!
Run Code Online (Sandbox Code Playgroud)

如果开发人员忘记image.png正确定位,则应该在早期开发中崩溃。一旦正确定位,该行就不会崩溃,因此没有理由处理可选路径。

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

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

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

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

如果潜在的崩溃可能是由意外数据(JSON 解析、用户输入等)引起的,那么永远不要使用!. 在这些情况下进行防御性编码。

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