代码之家  ›  专栏  ›  技术社区  ›  Tony Lin

为什么使用隐式展开或强制展开让应用程序在某个阶段崩溃并不有益?

  •  1
  • Tony Lin  · 技术社区  · 7 年前

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

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

    但在我看来,让应用程序在一些非常愚蠢的错误上崩溃是有利于开发阶段的开发人员的。 .

    我的例子是:

    class TopStoriesViewModelTests: XCTestCase {
        var viewModel: TopStoriesViewModel!
    
        override func setUp() {
            super.setUp()
            viewModel = TopStoriesViewModel(interactor: MockTopStoriesInteractor())
        }
    
        func testArticleDidVisited() {
            viewModel.visited = xxxxxx
        }
    }
    

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

    我的问题是,在某些特定情况下,比如我给出的例子中,强制展开/隐式展开是有益的,这一点我是否正确。

    1 回复  |  直到 7 年前
        1
  •  4
  •   rmaddy    7 年前

    当然。有许多适当的使用武力拆封,其中一个崩溃只会发生在早期的发展,因为一个错误已经作出,一旦修复,崩溃不会再发生。

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

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

    如果开发人员忘记瞄准 image.png 适当地。一旦目标正确,该行不会崩溃,因此没有理由处理可选路径。

    其他常见的例子是outlet。它们通常是隐式展开的,因为在视图控制器的代码中使用它们时,它们已经被附加。撞车可能意味着插座没有正确连接。修好了就不用担心了。无需处理警卫或其他可选检查。

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

    尽管如此,新的swift开发人员应该避免 ! 他们键盘上的字符有一段时间了。知道何时安全地使用它是一项有学问的技能。

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

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

    是的,有很多情况下,强制展开、强制转换和隐式展开变量是正确的选择。