2

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

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

但是,在我看来,由于隐含的 unwrap/force unwrap 让应用程序在一些非常愚蠢的错误中崩溃,这对处于开发阶段的开发人员是有益的

我的例子是:

class TopStoriesViewModelTests: XCTestCase {
    var viewModel: TopStoriesViewModel!

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

    func testArticleDidVisited() {
        viewModel.visited = xxxxxx
    }
}

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

我的问题是,我在某些特定情况下(例如我给出的示例)是否正确,强制展开/隐式展开是有益的。

4

1 回答 1

5

当然。强制展开有许多正确的用途,其中崩溃只会在开发早期发生,因为已经犯了错误并且一旦修复,崩溃就不会再次发生。

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

let imagePath = Bundle.main.path(forResource: "image", ofType: "png")!

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

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

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

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

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

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

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

于 2018-06-15T04:46:23.757 回答