swift - 从闭包中抛出错误

标签 swift closures throw

我的应用程序中有这段代码:

func saveContact2(contact: String) throws {
    let contactStore = CNContactStore()
    contactStore.requestAccess(for: .contacts, completionHandler: {(granted, error) in
        if granted && error == nil {
            //...
        } else {
            if !granted {
                throw contactErrors.contactAccessNotGranted(["Error","Access to Contacts is not granted."])
            }
        }
    })
}

我想将闭包中引发的所有错误抛给调用函数。

编译器显示错误:

Invalid conversion from throwing function of type '(_, _) throws -> ()' to non-throwing function type '(Bool, Error?) -> Void'

谁能用正确的语法帮助我?

最佳答案

您不能从异步调用的@escaping 闭包中抛出错误。这是有道理的,因为您的应用程序继续执行,没有地方可以捕获错误。

因此,改为自己采用完成处理程序模式:

func saveContact2(_ contact: String, completion: @escaping: (Result<Bool, Error>) -> Void) {
    let contactStore = CNContactStore()
    contactStore.requestAccess(for: .contacts) { (granted, error) in
        guard granted else {
            completion(.failure(error!)
            return
        }

        //...
        completion(.success(true))
    }
}

然后你会这样调用它:

saveContact2(contactName) { result in 
    switch result {
    case .failure:
        // handler error here

    case .success:
        // handle confirmation of success here
    }
}

如果您使用的是没有 Result 类型的旧编译器,它基本上是:

enum Result<Success, Failure> where Failure: Error {
    case success(Success)
    case failure(Failure)
}

关于swift - 从闭包中抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57021732/

相关文章:

Ruby Pascal 的带内存的三角形生成器

.net - 有没有一种简单的方法可以向 CaSTLe Windsor 注册静态闭包?

compiler-errors - 尽管受到限制,但值(value)还不够长

c++ - 当索引超出范围时,检索方法是否应该引发异常?

ios - 在 iOS 设备上运行 swift 应用程序时出现 THREAD 1 : EXC_BREAKPOINT (code = EXC_ARM_BREAKPOINT. ..) 错误

ios - Swift editActionsForRowAt 与 TrailingSwipeActionsConfigurationForRowAt TableView

ios - 为什么在设置 NSManagedObject 的属性时抛出异常?

uiviewanimation - 使用 Swift 的 UIView 动画选项

scala - 获取 URL 时最好返回 None 还是抛出异常?

c++ - 异常对象的静态类型