Multithreading in iOS| Difference between GCD and NSOperation

Basics of concurrency in iOS.

Threading is an important concept in iOS. The concept is pretty simple. This is what happens inside the processor. Consider launching an app in your iPhone. When the app launches, it will be on the main thread or the UI thread. At this point, when we try to do some time consuming task in the main thread, the UI will stop responding for a while. This is a situation the user will never want to face. From the users perspective, the app should always be responding and should be fast. As we know , most of the modern processors supports multitasking and are pretty fast. So, instead of doing the time consuming task in the main thread, better give it to different thread so that the main thread can do the other work it has to perform.

Consider an example of loading a tableview . You will be calling a method which takes some time say 5 seconds to return with the data for tableview and you will be doing this in the viewDidLoad().

override func viewDidLoad() {
super.viewDidLoad()
doSomeTimeConsumingTask() // takes 5 seconds to respond
tableView.reloadData()
}

The execution happens line by line and when doSomeTimeConsumingTask() method is called, the UI will not be responding for 5 seconds . So for the user, the app will not even show the table for 5 seconds. Then suddenly it gets the data and the tableview is loaded.

This actually is a bad practice as time consuming processes should be done in a separate thread say a “Background thread” to free up the main UI thread so that the app remains responsive.

Then how do we call the doSomeTimeConsumingTask() in a different thread?

We can use GCD or NSOperation to do this. Here I am using GCD. Well, that is pretty simple. We normally create a global thread with some priority level and assign the task to it.

DispatchQoS is the quality of service with determines the priority required for the task in the thread. As you can see, there are different priority levels available .

background has the lowest priority and userInteractive has the highest
Optimally, run your app at a QoS level of utility or lower at least 90% of the time when user activity is not occurring.
QoS is available in iOS 8 and later.

In the past, GCD has provided high, default, low, and background global concurrent queues for prioritizing work. Corresponding QoS classes should now be used in place of these queues.

So, for the above use case, create a global queue with User-Interactive QoS class so that it gets executed instantaneously.

The .async closure executes the code asynchronously without bothering about other tasks which are pending. The above code will work and it will reload the table but not instantaneously. This is because the reloadData() is called from the background thread. So, one more correction is required in the above code so that the tableview reloads properly. This is by calling the main thread and asynchronously reloading the table.

override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global(qos:.userInteractive).async {
self.doSomeTimeConsumingTask() // takes 5 seconds to respond
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}

Done. So, that was a small intro to threading in iOS. I will try to cover more in the next article.

Also, do read this article by RayWenderlich on GCD.

NSOperation and Grand Central Dispatch

Reference: StackOverflow, Cocoacasts, nhipster

You might have heard about the terms NSOperation and GCD. Let us understand what they are and when to use them.

Both NSQueueOperations and GCD allow executing heavy computation task in the background on separate threads by freeing the UI Application Main Tread.

  • GCD is a low-level C-based API interacts directly with Unix level of the system.
  • NSOperation and NSOperationQueue are high-level Objective-C classes.

NSOperationQueue is objective C wrapper over GCD. If you are using NSOperation, then you are implicitly using Grand Central Dispatch. That means, the NSOperation API is a higher level abstraction of Grand Central Dispatch which makes NSOperation slightly shower than GCD.

Always use the highest-level abstraction available to you, and drop down to lower-level abstractions when measurement shows that they are needed. But, many developers prefer to use GCD over NSOperation unless extremely necessary. Implementing GCD is lightweight compared to NSOperation.

Benefits of NSOperation

  • You can Pause, Cancel, Resume an NSOperation . With Grand Central Dispatch, you no longer have control or insight into the execution of that task. The NSOperation API is more flexible in that respect, giving the developer control over the operation's life cycle.
  • You can set up a dependency between two NSOperations . This is a powerful concept that enables developers to execute tasks in a specific order. An operation is ready when every dependency has finished executing.
  • Can monitor the state of an operation or operation queue. ready, executing or finished.
  • The NSOperation and NSOperationQueue classes have a number of properties that can be observed, using KVO (Key-Value Observing). This is another important benefit if you want to monitor the state of an operation or operation queue.
  • You can specify the maximum number of queued operations that can run simultaneously
“ when you want more control over queue (all above mentioned) use NSOperation and for simple cases where you want less overhead (you just want to do some work "into the background" with very little additional work) use GCD. 

Enjoy!!

If you enjoyed reading this post, please share and give some clapps so others can find it 👏👏👏👏👏 !!!!

You can follow me on Medium for fresh articles. Also, connect with me on LinkedIn.