如何在 iOS Swift 中进行多线程、并发或并行处理?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24589575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to do multithreading, concurrency or parallelism in iOS Swift?
提问by Martin Cazares
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)?
我已经阅读了 Apple Swift 文档的基本和高级组件,但没有关于并发或并行的内容,有没有人知道如何做(如果可能)?
回答by Rob
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 Guidefor the relative merits of operation queues and dispatch queues (aka Grand Central Dispatch, GCD). 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). The documentation for GCD and operation queues in Xcode describes both Objective-C and Swift APIs.
有关操作队列和调度队列(又名 Grand Central Dispatch,GCD)的相对优点,请参阅 Apple 的并发编程指南。虽然该指南仍在说明使用 Objective-C 的示例,但 API 和概念在 Swift 中基本相同(只需使用 Swift 语法)。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". 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):
顺便说一下,您会注意到,在上面的示例以及 Andy 的 GCD 演示中,我们都使用了“尾随闭包”。例如,如果您查看定义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 函数声明并在您的代码中使用它们。
回答by artey
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)
回答by Alex Lynch
This librarylets 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)
}
回答by Dhaval H. Nena
Here is the best resource to learn in detail about Councurrency
这是详细了解并发的最佳资源