我一直在努力,但是我不明白。我是编程新手,所以几乎每个新步骤都是一个实验。尽管在没有参数/返回值的情况下调度正常的闭包没有问题,但到目前为止,我还不了解如何处理带有(多个)参数并最终返回的函数。
为了弄清楚适当的“解决方法”的逻辑,如果有人可以发布一个实际的示例,这样我就可以确定自己是否正确,那就太好了。我将非常感谢您提供的任何帮助…如果其他一些实际示例以更好的方式说明了该主题,请继续尝试!
假设我们想异步地将以下函数分派到低优先级的后台队列中(或者我犯错了,在定义函数时尝试实现分派,而不是等到从其他地方调用它之前!):
func mutateInt(someInt: Int) -> Int { "someHeavyCalculations" return result }
或具有多个参数的函数,该函数另外还会在某个时候调用第一个函数(后台队列中的所有内容):
func someBadExample(someString: String, anotherInt: Int) -> Int { "someHeavyStuff" println(testString) mutateInt(testInt) return result }
或应确保仅在主队列上运行的UI函数(仅是一个虚构的示例):
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { let sectionInfo = self.fetchedResultsController.sections?[section] as NSFetchedResultsSectionInfo return sectionInfo.numberOfObjects }
假设您有一些类似的功能:
func calculate(foo: String, bar: Int) -> Int { // slow calculations performed here return result }
如果要异步执行此操作,则可以将其包装为以下内容:
func calculate(foo: String, bar: Int, completionHandler: @escaping (Int) -> Void) { DispatchQueue.global().async { // slow calculations performed here completionHandler(result) } }
或者,或者,如果您想确保始终在主队列上调用完成处理程序,则也可以这样做:
func calculate(foo: String, bar: Int, completionHandler: @escaping (Int) -> Void) { DispatchQueue.global().async { // slow calculations performed here DispatchQueue.main.async { completionHandler(result) } } }
对于在后台执行的工作,您可以使用其他优先级的后台队列,也可以使用自己的自定义队列或自己的操作队列。但是这些细节对于眼前的问题并不是很重要。
与此相关的是,即使基础同步函数会返回此值,该函数本身也不会返回任何值。取而代之的是,这种异步再现通过completionHandler闭包将值传递回去。因此,您可以这样使用它:
completionHandler
calculate(foo: "life", bar: 42) { result in // we can use the `result` here (e.g. update model or UI accordingly) print("the result is = \(result)") } // but don't try to use `result` here, because we get here immediately, before // the above slow, asynchronous process is done