如何在swift的闭包中抛出错误?

时间:2015-07-23 23:15:07

标签: ios error-handling closures swift2

请查看以下代码:

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)的抛出函数的无效转换抛出 - >虚空'到非投掷函数类型'(UITableViewRowAction,NSIndexPath) - >空隙'

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

2 个答案:

答案 0 :(得分:6)

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

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

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

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

答案 1 :(得分:2)

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

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

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

然后在闭包

中使用捕获的错误调用此函数