So Apple recommends that we avoid doing too much work on the main thread. This is great advice, the less time you spend wasting CPU cycles in the main thread, the more responsive your UI will be. In my opinion a well defined iOS application will avoid doing more than update the UI on the main thread.
One prime example I’ve run into was some code that did a synchronous network request. It waited for the network response before returning and someone thought it had to run on the main thread. This resulted in a lock-up during some animations I was working on.
There’s a number of topics1 that I plan to discuss about getting things off of the main thread, but today I’m going to discuss running things on the main thread.
If you’ve set up your app to do all of the heavy lifting in some secondary thread or in a dispatch queue, you will probably need to update you UI based on this work. The first thing you’re likely to do is simply update the UIView object:
Well, it turns out that doesn’t really do anything. You might get really lucky
and see the label update seconds or minutes later. The first thing to do is by
adding a call to
The next time the UI code checks to see if the UILabel has changed, it will see that, yes it has, and upate the display. Sadly, when this happens is often still fairly late.
To really get things updated,
setNeedsDisplay needs to be called from the
main thread, where the UI does its work. If you can ensure that your code runs
there, it should update with no noticable delay. Thankfully, Apple gave us a
wonderful tool for executing small bits of code anywhere on a specific thread
1 2 3 4
Suddenly your label updates the instant your code runs. The best part is it can be put in anywhere and since it runs on the main thread, the UI will update almost immediately.
So when you need to get some code to run on the main thread, usually to get
your UI to update with new information, you just use
dispatch_get_main_queue(). Now go forth, and write responsive UIs!