【问题标题】:Difference between return of Any vs Void in Async Block异步块中 Any 与 Void 的返回之间的区别
【发布时间】:2021-03-09 15:42:16
【问题描述】:

在这两个代码之间

(返回 -> 无效)

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

但是当改变它时

  • 来自Return -&gt; Void
  • Return -&gt; Any

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

“预期返回‘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

并作为可能的答案给出了这个 How I can return value from async block in swift

【问题讨论】:

  • 你需要做return value,或者价值或“随便”是Any。只是因为你可以有隐式return,当你写一行时,它会尝试将其转换为隐式返回。更多关于隐式返回github.com/apple/swift-evolution/blob/master/proposals/… 现在的问题是:你真的想返回Any 吗?你要返回哪个值,你真的会用吗?还是只是测试?
  • @Larme 我正在关注 SO stackoverflow.com/questions/52287840/…,这两个都是解决方案。
  • @Rob 我实际上想使用 dropboxWorkoutList 的返回值来填充我尚未编码的表格视图
  • @Rob 看起来确实合乎逻辑,但似乎与实际用途不符(如果您看到来自static func dropboxWorkoutList() -&gt; [String] 的最初问题)。用户想要管理正确的异步调用,你不能直接返回,你需要有一个闭包并了解异步是如何工作的。在其中,获得列表后,刷新 UI。
  • 您确实需要正确学习如何使用闭包/异步调用。您偶然发现任何教程都可以回答的简单问题

标签: ios swift closures


【解决方案1】:

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

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

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

您可能根本不想将闭包更改为([String]) -&gt; Any,而是将其保留为([String]) -&gt; 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 正在调用一个函数(在本例中为闭包)来表示“嘿,这是你的数据”。它向该闭包提供数据,而不是从该闭包返回数据。

【讨论】:

  • 是的。这正是我想要的。从异步中获取返回值,然后将其作为数据源传递给 tableview。您的解释还有助于区分AnyVoid提出的问题
猜你喜欢
  • 2020-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-08
  • 2015-09-26
  • 2012-07-01
  • 2023-01-08
  • 2021-09-09
相关资源
最近更新 更多