简体   繁体   English

如何在iOS Swift中进行多线程,并发或并行?

[英]How to do multithreading, concurrency or parallelism in iOS Swift?

Is there any way to create a worker thread in Swift?, for example, if there's a major functionality that requires a lot of calculations and hence causes the main thread to delay for a few seconds, if I would like to move that functionality to a separate thread or a thread that do not block the main thread is there any way to do it with Swift? 有没有办法在Swift中创建一个工作线程?例如,如果有一个主要功能需要大量的计算,从而导致主线程延迟几秒钟,如果我想将该功能移动到一个单独的线程或不阻塞主线程的线程有没有办法用Swift做?

I've gone through the basic and advanced components of the Apple Documentation for Swift but there's nothing about concurrency or parallelism, do anyone know something about how to do it(if possible)? 我已经浏览了Swift的Apple文档的基本和高级组件,但没有关于并发或并行的内容,有人知道如何做(如果可能的话)吗?

Or you can use operation queues, too. 或者您也可以使用操作队列。 In Swift 3: 在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
    }
}

Either this, or GCD, which Andy illustrated , work fine. 无论是这个,还是安迪所说的 GCD都可以正常工作。

See Apple's Concurrency Programming Guide for the relative merits of operation queues and dispatch queues (aka Grand Central Dispatch, GCD). 有关操作队列和调度队列(又名Grand Central Dispatch,GCD)的相对优点,请参阅Apple的并发编程指南 While that guide is still illustrating the examples using Objective-C, the API and concepts are basically the same in Swift (just use the Swift syntax). 虽然该指南仍然使用Objective-C来说明示例,但是Swift中的API和概念基本相同(只是使用Swift语法)。 The documentation for GCD and operation queues in Xcode describes both Objective-C and Swift APIs. Xcode中的GCD和操作队列文档描述了Objective-C和Swift API。


By the way, you'll notice that in both the above example as well as Andy's GCD demonstration, we used "trailing closures". 顺便说一下,你会注意到在上面的例子以及Andy的GCD演示中,我们使用了“尾随闭包”。 For example, if you look at the definition addOperationWithBlock , that is defined as a function with one parameter which is a "closure" (which is analogous to a block in Objective-C): 例如,如果你看一下addOperationWithBlock定义,它定义为一个带有一个参数的函数,它是一个“闭包”(类似于Objective-C中的一个块):

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

That might lead you to assume that you would invoke it as follows: 这可能会导致您假设您将按如下方式调用它:

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

But when the last parameter of a function is a closure, the trailing closure syntax allows you to take that final closure parameter out of the parentheses of the function, and move it after the function, yielding: 但是当函数的最后一个参数是闭包时,尾随闭包语法允许你从函数的括号中取出最后的闭包参数,并在函数之后移动它,产生:

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

And because there's nothing left in the parentheses, you can even go one step further, and remove those empty parentheses: 因为括号中没有任何内容,您甚至可以更进一步,删除那些空括号:

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

Hopefully that illustrates how to interpret the NSOperationQueue / OperationQueue and/or GCD function declarations and use them in your code. 希望这说明如何解释NSOperationQueue / OperationQueue和/或GCD函数声明并在您的代码中使用它们。

You can use Grand Central Dispatch (GCD) for such tasks. 您可以使用Grand Central Dispatch(GCD)执行此类任务。

This is a basic example: 这是一个基本的例子:

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)

This library lets you describe concurrency in a super expressive way: 这个库让你以超级表达的方式描述并发:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM