异步块中 Any 与 Void 的 return 之间的区别

Difference between return of Any vs Void in Async Block

在这两个代码之间

(returns -> 无效)

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: { [=11=] <  } )
        // 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

但是当改变它时

尝试执行以下命令时 swift 会告诉我:

"Missing return in a closure expected to return 'Any'"

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

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

注:问这个 Return list of files from function call

并给出了这个可能的答案

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

I actually want to use the return values from dropboxWorkoutList to populate a tableview which I've not coded yet

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

您可能根本不想将闭包更改为 ([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
}

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