7

How does code in main thread and its runloop interact? For example, does all code in main thread have to run until it is idle before hitting the runloop? Or does runloop check its sources in the middle of executing the code in main thread? Is it possible for runloop source to block main thread code from executing (since it's running on the same thread)?

I am trying to understand how main thread code fits into the picture of runloop (or vice versa) in the grand scheme of things.

Is this how a runloop looks like alongside our code:

Main thread:

  1. runloop runs at a specific interval
  2. runloop is done running, our code runs
  3. our code is done running, go to (1) (What if our code runs so long that runloop doesn't get a chance to run?)
Rob
  • 415,655
  • 72
  • 787
  • 1,044
Boon
  • 40,656
  • 60
  • 209
  • 315

2 Answers2

9

You asked:

How does code in main thread and its runloop interact?

The main runloop is just a loop that is being performed on the main thread.

What if our code runs so long that runloop doesn't get a chance to run?

If you block the main thread (i.e. you do something synchronously that is very slow) then the runloop, which called your code and is waiting for you to return, will not have a chance to continue looping, and thus everything contingent upon that (timers, sources, UI, etc.) will appear to freeze.

This is why, if you have any task that is going to take more than a few milliseconds, that you should dispatch it to some background queue, and get it off the main thread, and thus your code on the main thread can promptly return to the run loop and ensure that the main thread is not blocked. This will thereby ensure that the main runloop can continue operating and yield a responsive UI.

In terms of your three points in which you describe how the runloop works, I might describe it differently. It's not that the runloop "ends" and then your code runs. It's really that the runloop is looping, handling various system events (e.g. UI, timers, etc.) and that, in the process of handling those, it may end up calling your code (in which case the whole main thread, including the runloop, is blocked from proceeding until your code returns back to the runloop).

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks Rob, much clearer. Are events being observed by a runloop queued up? Meaning if I have a timer that fires very quickly, will it be processed first in the next runloop or after whatever event is already queued up in between loop? Also, does runloop process one event in each loop? – Boon May 07 '14 at 03:29
1

The runloop receives events from multiple sources and it handles those events. So, sending code to the main thread and/or pressing a button adds an event to the main runloop event queue and that event is handled when the runloop check its sources again. It doesn't suspend/lock in the middle of executing the current event.

Edit: seeing your edit, allow me to make this clarification: the runloop works with the main thread. The project template adds the runloop into our code and the runloop works with the tread to run the code. So "runloop is done running, our code runs" is incorrect, it's more like "the runloop receives an event from one of its sources telling it to run our code in this particular part".

J2theC
  • 4,412
  • 1
  • 12
  • 14
  • I understand this. I don't understand how an infinite loop doesn't block our code from running. Internally does the runloop get kicked off by a timer and exits itself when there is nothing to handle? – Boon May 06 '14 at 02:55
  • It's not just an infinitive loop. What the runloop does during the course of the application is to check for its input sources and verify if there is anything to process. If you do do an infinitive loop on the main thread you will lock the runloop and all code in the main thread. – J2theC May 06 '14 at 02:57
  • Is the runloop check kicked off by a timer behind the scene? Can it be kicked off in the middle of our code execution? – Boon May 06 '14 at 02:59
  • The runloop won't stop an event from terminating to check another event. So, if you lock the main thread while a timer is running, the timer will fail to fire. – J2theC May 06 '14 at 03:03
  • @Boon - Your code is all event-driven, as long as you create a `UIApplication` in main.m. See the UIApplication class reference. And no, your code is blocking unless explicitly threaded or asynchronous. Think of the hourglass or beachball-- that's blocking the run loop. – stevesliva May 06 '14 at 03:39
  • Nice [answer on CFRunLoop here](http://stackoverflow.com/questions/15161434/how-do-you-schedule-a-block-to-run-on-the-next-run-loop-iteration) – stevesliva May 06 '14 at 03:50