Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 我们是否总是需要在闭包中调用完成处理程序?_Ios_Swift_Closures - Fatal编程技术网

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

Ios 我们是否总是需要在闭包中调用完成处理程序?,ios,swift,closures,Ios,Swift,Closures,我有一个在闭包中被调用的完成处理程序。但是,只有在一切顺利时,才会调用完成处理程序。在发生错误的情况下,永远不会调用完成处理程序 func product(with id: String, _ completion: @escaping (Product) -> ()) { // Make a network request for the product ... if (product) { completion(product) }

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

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

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

    if (product) {
       completion(product)
    }
}

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

如果您不呼叫完成,则不会发生任何事情,因为完成呼叫者不会等待它

但如果您想涵盖所有情况,请尝试添加失败回调。例如:

func product(with id: String, _ success: @escaping (Product) -> (), failure: @escaping (Any) -> ())

在您的情况下,如果您将其视为一个完成,这意味着无论发生什么情况,都必须调用它(失败的成功与错误),它必须在流程完成时返回

您可以做的是将可选的
错误
产品
传递给完成闭包,然后检查错误是否为
nil

func product(with id: String, _ completion: @escaping (Product?, Error?) -> ()) {
    // in case of there is an error:
    completion(nil, error)
    return

    // if things went happy:
    completion(product, nil)
}
调用方法:

product(with: "ID") { (product, error) in
    guard let returnedError = error else {
        print(product)

        return
    }

    print(returnedError)
}
或:


严格地说,打电话的人根本不等待。将执行或不执行闭包中的代码

不过,返回错误也是一种很好的做法

一个聪明的方法就是这种类型

注意:函数声明中
完成
之前的下划线字符没有意义

product(with: "ID") { (product, error) in
    if let returnedError = error {
        print(returnedError)
        return
    }

    print(product)
}
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))
    }
}
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
   }
}