【问题标题】:Swift: Error handling with throwing escaped closure (confusing)Swift:抛出转义闭包的错误处理(令人困惑)
【发布时间】:2017-07-02 02:52:19
【问题描述】:

我正在尝试使用 UIAlertController 提供一种处理错误的好方法,该控制器可以选择重试导致错误的代码。我想出了这个巨大的混乱,不知何故实际上有效:

func handleError(_ closure: @escaping () throws -> Void) {
  do {
    try closure()
  } catch {
    print(error)
    let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
    let retry = UIAlertAction(title: "Retry", style: .default, handler: {(_: UIAlertAction) in self.handleError(closure)})
    alert.addAction(retry)
    let cancel = UIAlertAction(title: "Cancel", style: .cancel)
    alert.addAction(cancel)
    present(alert, animated: true)
  }
}

但是,单看这一点,似乎它会导致比阻止错误更多的错误。我能做些什么来使这个简单或不那么混乱吗?我不明白为什么我需要 @escaping 部分(但编译器告诉我需要),或者为什么我需要为 UIAlertAction 闭包提供一个空白参数。

我只是需要一些保证,这不是一个太糟糕的解决方案。

【问题讨论】:

    标签: ios swift error-handling uialertcontroller


    【解决方案1】:

    @escaping 的想法是让您知道您的闭包将在异步调用中执行。这样想:假设你必须调用一个不是你自己开发的函数,并且必须向它传递一个闭包。现在假设您期望闭包将作为同步调用执行。你怎么知道它是否只用作同步调用? Swift 使用 @escaping 注释来给你这个保证。如果在任何异步调用中使用该函数,您必须在函数签名中告知这一点。在您的情况下,您将函数传递给将等待用户操作调用闭包的 AlertController。

    关于空白参数,实际上这不是一个空白参数,它是一个函数签名。在这里,您告诉编译器您将接收一个函数作为参数,并且该函数没有参数并且不返回任何内容,但可以抛出异常。在swift中,函数有类型。接收字符串作为参数并返回布尔值的函数属于(String)-> Bool 类型。使用空参数,您正在定义您将接受作为参数的函数的类型,在这种情况下,您的函数类型是() -> (),可以概括为(),意思是:没有参数的函数和什么都不返回。

    您可以在 swift here 中找到有关函数类型的更多信息。

    顺便说一句,我认为您的代码是正确的。我看不出有什么问题,但为了给你一个正确的回应,我必须知道你的关闭会发生什么。

    【讨论】:

    • 闭包可以是任何需要在其前面“尝试”才能工作的代码。我想到处用它做各种事情
    • 与try和闭包没有关系。在调用任何可能引发异常的函数之前,您必须使用 try。如果操作可以抛出异常(认为是受控错误),则必须使用 try。闭包是一种特殊类型的函数,您可以将其作为参数传递给其他函数。
    • 这段代码有什么可以简化的吗?我主要考虑的是 (_: UIAlertAction) 部分
    • 我不这么认为。这有点令人困惑,因为它做得非常简单。您可以使事情更清楚,但您需要使其更详细。也许其他人可以有不同的意见。
    猜你喜欢
    • 1970-01-01
    • 2015-03-15
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    相关资源
    最近更新 更多