我想知道是否有人知道使用Swift在iOS中同时运行x
个线程的直接方式。我试图将照片分成多个部分并同时进行分析。我已经调查了它,并且使用主线程和后台线程有很多讨论和示例,但我似乎找不到任何运行超过这2个线程的示例。例如在Java中,我可以这样做:
public class ConcurrentAnalysis implements Runnable
{
private static volatile int counter = 0;
public void run()
{
// Increment count by 2
counter += 2;
}
public static void main(String args[])
{
Thread thread1 = new Thread();
Thread thread2 = new Thread();
thread1.start();
thread2.start();
try
{
thread1.join();
thread2.join();
}
catch (InterruptedException e){ System.out.println("Exception Thrown: " + e.getMessage()); }
}
}
我知道在这个例子中我只使用了2个线程,但我可以添加尽可能多的线程。我真的只是尝试做类似于上面的Java代码,但在Swift中。
答案 0 :(得分:2)
<强> 1 即可。不要直接使用线程。有更好的解决方案:
有一个很棒的图书馆可供使用GCD - Async
NSOperationQueue - 当您需要控制执行操作的顺序时非常棒。
<强> 2 即可。不要在线程之间共享可变数据
如果你这样做,你需要一些同步机制,如:locks,mutex。
这种架构真的很难用。
第3 即可。使用不可变数据结构
不可变数据结构在多线程中是安全的,因为没有人不能改变它们,所以你可以安全地同时处理许多线程中的数据(读取)。
structs
是不可变的值类型,是多线程的绝佳解决方案。
更好的解决方案
线程获取输入数据,处理它并返回结果 通过这种方式,您可以使线程不设防,并且可以同时按下相同的图像。
示例:
class Multithread {
func processImage(image: UIImage, result:(UIImage -> Void) ) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
//Do what you want with image because UIImage is immutable
//Do work with image
var resultImage = image
let data = resultImage.CGImage
//pass result to the calling thread, main threa in our example
dispatch_async(dispatch_get_main_queue()) {
//assign new image
result(resultImage)
}
}
}
}
// Use example
if let image = UIImage(named: "image") {
let worker = Multithread()
//Run multiple workers.
worker.processImage(image) { resultImage in
//result
println(resultImage)
}
worker.processImage(image) { resultImage in
//result
println(resultImage)
}
worker.processImage(image) { resultImage in
//result
println(resultImage)
}
worker.processImage(image) { resultImage in
//result
println(resultImage)
}
}
如果您使用Async框架,processImage
的外观如下:
func processImage(image: UIImage, result:(UIImage -> Void) ) {
Async.background {
//Do what you want with image because UIImage is immutable
//Do work with image
var resultImage = image
let data = resultImage.CGImage
//pass result to the calling thread, main threa in our example
Async.main {
//assign new image
result(resultImage)
}
}
}