【问题标题】:How to do multithreading, concurrency or parallelism in iOS Swift?如何在 iOS Swift 中进行多线程、并发或并行?
【发布时间】:2014-08-26 16:40:40
【问题描述】:

有什么方法可以在 Swift 中创建工作线程吗?例如,如果有一个主要功能需要大量计算并因此导致主线程延迟几秒钟,如果我想移动它单独线程或不阻塞主线程的线程的功能有没有办法用 Swift 做到这一点?

我已经浏览了 Apple Swift 文档的基本和高级组件,但是没有关于并发或并行性的内容,有人知道如何做吗(如果可能的话)?

【问题讨论】:

  • 尝试在 Obj-C 中执行此操作
  • CwlUtils 可能有用。

标签: ios multithreading concurrency swift multitasking


【解决方案1】:

或者您也可以使用操作队列。在 Swift 3 中:

let queue = OperationQueue()

queue.addOperation() {
    // do something in the background

    OperationQueue.main.addOperation() {
        // when done, update your UI and/or model on the main queue
    }
}

无论是这个还是 GCD,Andy illustrated,都可以正常工作。

请参阅 Apple 的 Concurrency Programming Guide,了解操作队列和调度队列(又名 Grand Central Dispatch,GCD)的相对优点。虽然该指南仍在说明使用 Objective-C 的示例,但 API 和概念在 Swift 中基本相同(只需使用 Swift 语法)。 Xcode 中 GCD 和操作队列的文档描述了 Objective-C 和 Swift API。


顺便说一句,您会注意到在上面的示例以及 Andy 的 GCD 演示中,我们都使用了“尾随闭包”。例如,如果您查看addOperationWithBlock 的定义,它被定义为具有一个参数的函数,即“闭包”(类似于 Objective-C 中的块):

func addOperation(_ block: @escaping () -> Swift.Void)

这可能会导致您假设您会按如下方式调用它:

queue.addOperation({
    // do something in the background
})

但是当函数的最后一个参数是闭包时,尾随闭包语法允许您将最后的闭包参数从函数的括号中取出,并将其移到函数后面,从而产生:

queue.addOperation() {
    // do something in the background
}

因为括号里什么都没有了,你甚至可以更进一步,去掉那些空括号:

queue.addOperation {
    // do something in the background
}

希望这能说明如何解释 NSOperationQueue/OperationQueue 和/或 GCD 函数声明并在您的代码中使用它们。

【讨论】:

    【解决方案2】:

    您可以使用 Grand Central Dispatch (GCD) 来执行此类任务。

    这是一个基本的例子:

    let backgroundQueue: dispatch_queue_t = dispatch_queue_create("com.a.identifier", DISPATCH_QUEUE_CONCURRENT)
    
    // can be called as often as needed
    dispatch_async(backgroundQueue) {
        // do calculations
    }
    
    // release queue when you are done with all the work
    dispatch_release(backgroundQueue)
    

    【讨论】:

      【解决方案3】:

      This library 让你以超有表现力的方式描述并发:

      func handleError(_ error) { ... }
      
      HoneyBee.start(on: DispatchQueue.main) { root in
          root.setErrorHandler(handleError)
              .chain(function1) // runs on main queue
              .setBlockPerformer(DispatchQueue.global())
              .chain(function2) // runs on background queue
              .branch { stem in
                  stem.chain(func3) // runs in parallel with func4
                  +
                  stem.chain(func4) // runs in parallel with func3
              }
              .chain(func5) // runs after func3 and func4 have finished
              .setBlockPerformer(DispatchQueue.main)
              .chain(updateUIFunc)
      }
      

      【讨论】:

        【解决方案4】:

        这里是详细了解的最佳资源 Councurrency

        【讨论】:

          猜你喜欢
          • 2018-10-07
          • 2022-06-10
          • 2021-12-12
          • 1970-01-01
          • 1970-01-01
          • 2019-04-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多