What's the best way of multithreading in iOS as we have three options GCD, NSThread
, and NSOperationQueue
? I am confused in which one is the best? If none, then which should be used in what scenario and how they differ and also, if someone has some good example of using NSOperationQueue
, please share so that I can learn.

- 415,655
- 72
- 787
- 1,044

- 647
- 3
- 10
- 24
-
1Define "best". Fastest, lightest, easiest to use? – CodaFi Oct 21 '12 at 06:16
-
This is an unanswerable question unless you have a specific use case in mind. There is no generic "best" out of the three. – jrturton Oct 21 '12 at 07:49
2 Answers
Simple answer:
Use NSThread (or even the pthreads API) when you want or need to have direct control over the threads you create, e.g. you need fine-grained control over thread priorities or are interfacing with some other subsystem that vends/consumes thread objects directly and you need to stay on the same page with it. Such instances are rare, but they do occur, particularly in real-time applications.
Use GCD when your task lends itself well to simple parallelization, e.g. you just want to toss some work "into the background" with very little additional work, you have some data structures that you merely wish to serialize access to (and serial queues are great for doing that in a lockless fashion), you have some for loops that would lend themselves well to parallelization with dispatch_apply(), you have some data sources / timers that GCD's sources API will enable you to deal with easily in the background, etc etc. GCD is quite powerful and you can use it for a lot more than this, but these are all relative 'no brainer' scenarios where you don't want to get caught up in the initialization and setup tasks so much as simply "do basic stuff in parallel".
Use NSOperation when you're already up at the Cocoa API layer (vs writing in straight C to the POSIX APIs) and have more complex operations you want to parallelize. NSOperation allows for subclassing, arbitrarily complex dependency graphs, cancellation and a supports a number of other higher-level semantics that may be useful to you. NSOperation actually uses GCD under the covers so it's every bit as multi-core, multi-thread capable as GCD, though it also brings the Foundation framework along for the ride so if you're hacking at the POSIX layer, you probably want to use option #2.
As others have said, however, it all depends on What You Are Trying To Do so there's no single or even universally correct answer to your question.

- 3,246
- 16
- 13
-
1KUdos,...@jkh ......this is what i wanted to know. Now, there is somebody with whom i cn discuss. Okay, so you said about point 2, i am currently using 2. But, i was thinking if can set the priority of thread at runtime based on time taken by some other thread or queue. Suppose, a thread is taking more than 3 min then, i want to lower the priority of it and increase the priority of second one. – Sumitiscreative Oct 23 '12 at 14:53
-
Also, as we have dispatch_global queue in ios, which are concurrent by nature. When we assign block of code to it Then, is this better than making a new custom concurrent queue and adding blocks to it ??? or its the same??? can we set the priority of these queues that we create??? – Sumitiscreative Oct 23 '12 at 14:57
-
2Before setting the priority of a thread, the first question to ask is "Why?" I cited real-time applications (audio, video processing for example) as the primary reason for doing so since it's rare to need to do so otherwise. GCD provides 4 levels of priority in the global concurrent queues (background, low, medium, high) which are almost always enough for an application's needs. If a thread is taking 3 minutes to complete, setting priority won't help - either break it into smaller tasks or simply let the OS dynamically set priorities for long-running threads vs short-term ones (and it will) – jkh Oct 24 '12 at 03:37
-
Regarding using global concurrent queues vs custom ones you create yourself, it all depends. You usually create your own queues when you want to associate state with the queues (dispatch_{set,get}_specific()) or cannot use the global ones for some other reason (you want to suspend/resume them for example). Otherwise it's just fine to use the global ones, particularly as ones you create yourself all run at the same priority, unlike the 4 global concurrent queues (see above comment). – jkh Oct 24 '12 at 03:39
-
ok that was helpful...and it clears pretty well the scope for which i was looking for...thanks – Sumitiscreative Oct 25 '12 at 06:40
I have been leaning towards NSOperationQueue lately. This uses GCD internally and is thread safe, as well is very simple to use.

- 4,952
- 3
- 23
- 26
-
But one could argue that it would certainly be faster to ditch NSOperationQueue, and simply drop down to the GCD level. – CodaFi Oct 21 '12 at 06:17
-
NSOperationQueue works best when tasks are discrete, synchronous and live in the same thread (eg they are more or less atomic), the queue can be used as basic thread pool though in almost any situation. – deleted_user Oct 21 '12 at 06:19