我们是否总是需要在闭包中调用完成处理程序?

Sam*_*nez 3 closures ios swift

我有一个在我的闭包内被调用的完成处理程序。但是,只有在一切顺利时才会调用完成处理程序。在发生错误的情况下,完成处理程序永远不会被调用。

func product(with id: String, _ completion: @escaping (Product) -> ()) {

     // Make a network request for the product
     ...

    if (product) {
       completion(product)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个糟糕的设计吗?我最近收到一条评论,即使出现错误也需要调用完成处理程序,否则调用者将无限期地等待。我以前从未听说过,现在我想知道这是否适用于 Swift。

vad*_*ian 6

严格地说,来电者根本不等待。闭包中的代码会或不会被执行。

然而,返回错误也是一个好习惯。

一个聪明的方法是Result类型

func product(with id: String, completion: @escaping (Result<Product,Error>) -> Void) {

     // Make a network request for the product
     ...
    if error = error { completion(.failure(error)); return }

    if product {
       completion(.success(product))
    } else {
       let error = // create some other error
       completion(.failure(error))
    }
}
Run Code Online (Sandbox Code Playgroud)

并称之为

product(with: "Foo") { result in
   switch result {
     case .success(let product): // do something with the product
     case .failure(let error): // do something with the error
   }
}
Run Code Online (Sandbox Code Playgroud)

注意:completion函数声明之前的下划线字符是没有意义的。