iOS - 在多个线程上处理照片

时间:2015-04-25 04:18:52

标签: ios multithreading swift

我想知道是否有人知道使用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中。

1 个答案:

答案 0 :(得分:2)

<强> 1 即可。不要直接使用线程。有更好的解决方案:

有一个很棒的图书馆可供使用GCD - Async
NSOperationQueue - 当您需要控制执行操作的顺序时非常棒。

<强> 2 即可。不要在线程之间共享可变数据

如果你这样做,你需要一些同步机制,如:locks,mutex。
这种架构真的很难用。

第3 即可。使用不可变数据结构
不可变数据结构在多线程中是安全的,因为没有人不能改变它们,所以你可以安全地同时处理许多线程中的数据(读取)。

Swift中的

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