一尘不染

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

swift

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

为了弄清楚适当的“解决方法”的逻辑,如果有人可以发布一个实际的示例,这样我就可以确定自己是否正确,那就太好了。我将非常感谢您提供的任何帮助…如果其他一些实际示例以更好的方式说明了该主题,请继续尝试!

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

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
}

阅读 214

收藏
2020-07-07

共1个答案

一尘不染

假设您有一些类似的功能:

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
2020-07-07