0

Apple's official documentation is sometimes difficult for understanding, especially for non-native speakers. This is an excerpt from Anatomy of NSRunLoop

A run loop is very much like its name sounds. It is a loop your thread enters and uses to run event handlers in response to incoming events. Your code provides the control statements used to implement the actual loop portion of the run loop—in other words, your code provides the while or for loop that drives the run loop. Within your loop, you use a run loop object to "run” the event-processing code that receives events and calls the installed handlers.

This confuses me. My code never provides while or for loops even for non-main threads. What is being meant here? Can anyone explain?

Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161
  • See the discussion : http://stackoverflow.com/questions/12091212/understanding-nsrunloop http://stackoverflow.com/questions/6216664/is-there-any-guide-for-ios-runloop-mechanism – LML Feb 19 '14 at 10:45
  • This is easy to understand: [Friday Q&A 2010-01-01: NSRunLoop Internals](https://www.mikeash.com/pyblog/friday-qa-2010-01-01-nsrunloop-internals.html) – Amar Feb 19 '14 at 10:48
  • i've seen both but none contains an answer to my question. at least i can't find it there – Andrey Chernukha Feb 19 '14 at 10:49

2 Answers2

2

Keep reading until Using Run Loop Objects and Apple’s code samples do show control statements like while loops.

Listing 3-1

NSInteger loopCount = 10;
do
{
    // Run the run loop 10 times to let the timer fire.
    [myRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
    loopCount--;
}
while (loopCount);

Listing 3-2

do
{
    // Start the run loop but return after each source is handled.
    SInt32 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES);

    // If a source explicitly stopped the run loop, or if there are no
    // sources or timers, go ahead and exit.
    if ((result == kCFRunLoopRunStopped) || (result == kCFRunLoopRunFinished))
        done = YES;

    // Check for any other exit conditions here and set the
    // done variable as needed.
}
while (!done);

The intended way to use NSRunLoop does require you to invoke the next run, again and again until a certain condition is met.

But if you start your run loop with -[NSRunLoop run], it runs indefinitely without help. That’s what the main thread does.

In case you’re wondering why Apple lets (or wants) you to control every loop, NeXTSTEP shipped in the 80s when every CPU cycle counts. Functions like -[NSRunLoop runMode:beforeDate:] lets you fine tune the frequency and behaviour of your run loops down to every run.

Jay Jun
  • 221
  • 2
  • 6
1

Oh, you do run a loop on the main thread, but you don't know.

Set a breakpoint on an action method and look at the stack trace. There will be something like:

#9 0x00007fff912eaa29 in -[NSApplication run] ()

That's the loop.

In another thread you very often do not need a instance of NSRunLoop. Its primary ability is to receive events and to dispatch them. But in an additional thread you want to process calculations straight forwarded in most cases. To have a term for it: Additional threads are usually not event-driven.

So you have a run loop (and have to run it) only rarely, especially when you have networking or file access that is dispatched using a run loop.In such a case it is a common mistake that one does not run the thread's run loop.

Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
  • thank you for your answer. so do i understand right that these words "in other words, your code provides the while or for loop that drives the run loop" mean that my code provides those loops IMPLICITLY without me actually writing this code? – Andrey Chernukha Feb 19 '14 at 10:58
  • 1
    It is done by `NSApplication` inside `NSApplicationMain()`. This function is called in your source code (generated by Xcode) in main.m. Yes, you do not have to type it explicitly. – Amin Negm-Awad Feb 19 '14 at 11:01