【问题标题】:how to throw errors in a closure in swift?如何快速在闭包中抛出错误?
【发布时间】:2015-10-14 11:34:04
【问题描述】:

请看以下代码:

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {

   let deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete", handler: {
        (action : UITableViewRowAction, indexPath : NSIndexPath)  -> Void  in

        if let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext{
            let restaurantToDelete = self.fetchResultController.objectAtIndexPath(indexPath) as! Restaurant
            managedObjectContext.deleteObject(restaurantToDelete)

            // Saving managedObjectContext instance, and catch errors if it fails
            do {
                try managedObjectContext.save()
            } catch let error as NSError {
                print("Error: \(error.localizedDescription)")
            }

        }

    })
    return deleteAction
}

来自 Xcode 的错误消息是:从类型 '(UITableViewRowAction, NSIndexPath) throws -> Void' 到非抛出函数类型 '(UITableViewRowAction, NSIndexPath) -> Void' 的无效转换

我知道问题是 managedObjectContext.save() 会抛出错误,这在完成处理程序中是不允许的。我发现一些博客文章修改了闭包参数以使闭包中的错误处理可行。虽然这里函数的定义是由苹果给出的,那么我该如何解决这个问题呢?非常感谢! :D

【问题讨论】:

    标签: ios error-handling closures swift2


    【解决方案1】:

    编译器正在将throws 添加到您的块的签名中,因为您的catch 子句并不详尽:模式匹配let error as NSError 可能会失败...请参阅documentation

    闭包参数的签名是(UITableViewRowAction, NSIndexPath) -> Void,但是编译器会推断您提供的闭包类型是(UITableViewRowAction, NSIndexPath) throws -> Void

    通过在您已经拥有的子句之后添加另一个 catch 子句(没有模式),编译器将看到您正在本地捕获异常,并且它不再推断您提供的闭包签名包括 @987654328 @:

    do {
      try managedObjectContext.save()
    } catch let error as NSError {
      print("Error: \(error.localizedDescription)")
    } catch {}
    

    【讨论】:

    • @user3788747 试一试并报告!
    • 是的,你是对的!非常感谢!但我仍然无法理解背后的原因。再次感谢您!
    • @user3788747 太好了!答案更新了更详细的解释(和文档链接),准备好让您接受 - 很乐意提供帮助!
    【解决方案2】:

    不可能,因为可以随时调用闭包,可能不会在函数执行时调用,那么错误应该传播到哪里?

    你必须调用另一个可以处理错误的函数:

    func handleError(error: ErrorType) {
        switch error {
            ...
        }
    }
    

    然后用你在闭包中捕获的错误调用这个函数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-20
      • 2012-05-05
      • 2018-01-06
      • 1970-01-01
      • 1970-01-01
      • 2020-10-23
      • 1970-01-01
      • 2020-03-02
      相关资源
      最近更新 更多