Reputation: 537
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
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