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

标签 swift grand-central-dispatch ios8

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

要获得正确“变通办法”的逻辑,如果有人可以发布一个实际示例,这样我就可以看看我是否完全正确,那就太好了。如果有任何帮助,我将不胜感激...如果其他一些实际示例以更好的方式说明了该主题,请继续使用您自己的示例!

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

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 闭包将值传回。因此,您可以像这样使用它:

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

关于swift - 如何以正确的方式在 Swift 中调度函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25740779/

相关文章:

ios - 如何在 Swift 中实现 didReceiveMemoryWarning?

ios - 如何检查全局调度队列是否为空?

ios - 如何检测用户是否在我的应用程序中为本地通知设置了横幅样式警报或 'normal' 样式警报?

ios - 如何在 iOS8.1 上使用 Swift 按顺序拍摄多张照片(每张延迟 1 秒)?

ios - SSL_ERROR_SSL(1) : operation failed within the library

ios - 为什么第二部手机与设备配对后,CBCentralManager 会向第一部手机报告 "Peer removed pairing information"?

带有 DISPATCH_TIME_FOREVER 的 swift 4.0 dispatch_semaphore_wait

swift - 我需要在 main_queue 上哪里使用dispatch_async?

ios - 展开 CLLocation 位置坐标时出现 fatal error

swift - 是否可以使用 'if-case' 代替具有逗号分隔列表的开关?