如何以正确的方式在Swift中调度函数?

时间:2014-09-09 09:11:35

标签: swift grand-central-dispatch ios8

我一直在努力,但我只是不明白。我对编程很陌生,所以几乎每一个新步骤都是一个实验。虽然在没有参数/返回的情况下调度普通闭包没有问题,但到目前为止我还没有理解如何处理带有(多个)参数并最终返​​回的函数。

为了获得正确的“解决方案”的逻辑,如果有人可以发布一个实际的例子,那将是很好的,所以我可以看到我是否已经完成了所有这些。我会非常感谢任何帮助...如果其他一些实际例子以更好的方式说明了这个话题,请继续自己做!

假设我们想要将以下函数异步调度到具有低优先级的后台队列(或者我犯了错误,在定义函数时尝试实现调度而不是等到从其他地方调用它? !):

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
}

1 个答案:

答案 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。)