我一直在努力,但我只是不明白。我对编程很陌生,所以几乎每一个新步骤都是一个实验。虽然在没有参数/返回的情况下调度普通闭包没有问题,但到目前为止我还没有理解如何处理带有(多个)参数并最终返回的函数。
为了获得正确的“解决方案”的逻辑,如果有人可以发布一个实际的例子,那将是很好的,所以我可以看到我是否已经完成了所有这些。我会非常感谢任何帮助...如果其他一些实际例子以更好的方式说明了这个话题,请继续自己做!
假设我们想要将以下函数异步调度到具有低优先级的后台队列(或者我犯了错误,在定义函数时尝试实现调度而不是等到从其他地方调用它? !):
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
}
答案 0 :(得分:23)
让我们说你有这样的功能:
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
闭包传递值。因此,您可以这样使用它:
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
(仅供参考,以上所有示例均为Swift 3.对于Swift 2.3再现,请参阅previous version of this answer。)