steveclark
steveclark

Reputation: 537

iOS - Process photo on multiple threads

I was wondering if anyone knew of a straight forward way to run x amount of threads concurrently in iOS using Swift. I am trying to split a photo into multiple sections and analyze them concurrently. I have looked into it and there is a lot of talk and examples using the main thread and the background thread, but I can't seem to find any examples that run more than those 2 threads. For example in Java I could do:

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

I know I only used only 2 threads in this example, but I could have added as many threads as I wanted. I am really just trying to do something similar to the above Java code but in Swift.

Upvotes: 0

Views: 1170

Answers (1)

Kostiantyn Koval
Kostiantyn Koval

Reputation: 8483

1. Don't use thread directly. There are better solutions:

There is a great library for working with GCD - Async
NSOperationQueue - is great when you need to control the order of the executed operation.

2. Don't share mutable data between threads

If you do that than you need some synchronisation mechanism like: locks, mutex.
It is really hard to work wit this architecture.

3. Use immutable data structure
Immutable data structures are safe to work in multithread because no one can't mutate them so you can safely work with data (read) in many thread simultaneously.

structs in Swift are immutable value types that are great solution for multithreading.

Better solution

The thread get input data, process it and return result.
This way you make your thread undefended and they can press the same image simultaneously.

Example:

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

Here is how the processImage would look like if you use Async framework:

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

Upvotes: 2

Related Questions