首页 > 解决方案 > 异步块中 Any 与 Void 的返回之间的区别

问题描述

在这两个代码之间

(返回 -> 无效)

static func dropboxWorkoutList ( userCompletionHandler: @escaping ([String]) -> Void) {
  let client  = DropboxClientsManager.authorizedClient
  var files: [String] = []

  _ = client?.files.listFolder(path: "/workouts")
    .response { response, error in
      if let result = response {
        for entry in result.entries {
          if let file = entry as? Files.FileMetadata {
            let ext = (file.name as NSString).pathExtension
          
            switch ext {
            case "txt", "mrc", "zwo":
              //  print("filename:\(file.name) ext:\(ext) path:\(file.pathLower)")
              files.append(file.pathLower!)
            
            default:
              continue
            }
          }
        }
        files = files.sorted(by: { $0 < $1 } )
        // print("Contents of Workout Folder:\(files)")
      userCompletionHandler(files)
    } else if let error = error {
      print(error)
    }
  }
}

叫它

dropboxFunc.dropboxWorkoutList() { (value) in
  print("value:\(value)")
  print("value[0] : \(value[0])")
  print("value.count : \(value.count)")
}

结果是:

value:["/1-01.txt", "/1-17.txt"]
value[0] : /1-01.txt
value.count : 5

但是当改变它时

尝试执行以下操作会迅速告诉我:

“预期会返回‘Any’的闭包中缺少返回”

dropboxFunc.dropboxWorkoutList() { (value) in
  print("value:\(value)")
  print("value[0] : \(value[0])")
  print("value.count : \(value.count)")
}

我只能允许执行 1 个打印语句。只是想了解其中的区别。

注意: 从函数调用中询问此文件的返回列表

并作为可能的答案给出了 我如何快速从异步块返回值

标签: iosswiftclosures

解决方案


指定闭包([String]) -> Any意味着闭包将返回一些东西,并且它的类型是Any。但是在您的示例中,(a)您的闭包根本没有返回任何东西;(b)dropboxWorkoutList无论如何,似乎不需要/使用调用者提供的闭包返回的对象。这是一种“完成处理程序闭包”模式,完成处理程序闭包几乎总是有一个Void返回类型。

我实际上想使用返回值dropboxWorkoutList来填充我尚未编码的表格视图

好的,那么我认为您可能将闭包参数(dropboxWorkoutList将提供给调用者的内容)和闭包的返回值(不太常见的情况,调用者需要dropboxWorkoutList根据闭包的参数提供一些值)混为一谈。在这种情况下,您需要前者(闭包参数),而不是后者(闭包的返回值)。

您可能根本不想将闭包更改为([String]) -> Any,而是将其保留为([String]) -> Void。调用者应该只接受闭包的参数并使用它。例如:

dropboxFunc.dropboxWorkoutList { values in
    self.strings = values        // update whatever model object your table view data source is using
    self.tableview.reloadData()  // and tell the table view to reload the data
}

简而言之,您在这里(以及其他帖子)的问题实际上是“我如何使用闭包返回一个值?”,答案是您不应该将其视为“返回”一个值。相反,在具有完成处理程序闭包的异步例程中,结果作为参数提供给闭包。本质上,dropboxWorkoutList是调用一个函数(在这种情况下是一个闭包)来说“嘿,这是你的数据”。它向该闭包提供数据,而不是从该闭包返回数据。


推荐阅读