views:

195

answers:

3

Before keeping on reading in the docs, my brain got stuck at this point:

- (void)threadMainRoutine {
    BOOL moreWorkToDo = YES;
    BOOL exitNow = NO;

    NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; // is this THE run loop?

    // some stuff...

    while (moreWorkToDo && !exitNow) { // or is THIS the run loop?
     // some stuff

     [runLoop runUntilDate:[NSDate date]];

     // some stuff
    }

    // some stuff
}

I've added some comments in the code example. Maybe someone can explain this, why there's a while loop if there's a runLoop object that receives a -runUntilDate: message. I mean: Who is the loop here? I see two. First the while that's obviously a running loop, and then it calls a method that sounds like running a loop a well.

stateConfused = YES;
pleaseExplain = YES;
+1  A: 

One is an object responsible for maintaining the run loop's state, the other is an actual loop.

Azeem.Butt
how would [runLoop runUntilDate:[NSDate date]]; maintain the state of the while loop? just by changing that exitNow entry of the threads dictionary to YES?
HelloMoon
The object maintains a wide variety of callback handlers which all must register themselves with a run loop object if they expect to get any execution time.
Azeem.Butt
+1  A: 

the first one is the actual runloop, the runloop returned by [NSRunLoop currentRunLoop] is created by the UIApplication. Simplified, it receives all the OS events (Keyboard, Mouse etc.) and dispatches them to your program. If you call [runLoop runUntilDate:[NSDate date]]; this will return after the specified date has passed but your program will continue to receive OS events. See this link.

This is different from calling:

[[NSThread currentThread] sleepFormTimeInterval:]

,which would send your thread to sleep completely and it won't even receive OS events.

Johannes Rudolph
+2  A: 

Technically, the NSRunLoop loops internally (it loops "until date"). This gives you a periodic opportunity to quit the thread -- if you use run instead of runUntilDate: then the NSRunLoop will loop internally forever (you won't need to wrap it in a while loop but you can never stop it either). This is the normal behavior for the main thread, not worker threads which typically have exit conditions that need periodic checking.

The runLoop will never change the value of moreWorkToDo or exitNow (you are responsible for doing this when the thread's work is done or the user has quit your application) but these are how you decide if you want the thread to terminate.

Depending on how you want your thread to behave, you can replace these flags with [NSApp isRunning] and [tasksRemainingForThisThreadToProcess count] != 0 or similar.

(Race condition warning: If you end the thread when all remaining tasks are processed, be careful to never send another task to the thread when the tasksRemainingForThisThreadToProcess is empty since this is an indication that the thread will quit).

Matt Gallagher