It is normal to run CFRunLoopRun on any thread that you want to have a run loop. It's run by the main thread at the start of most Cocoa programs, but if you create additional threads that need their own run loops, it would be fairly normal to run it there as well. I often use this when building command-line apps that need access to Cocoa. As an example of why you'd do this, it's required if you want to use NSTimer on a background thread. (I've seen people try to do this inside of GCD queues, but that's usually a mistake. Queues are not threads.) That said, since 10.6, IMO it's generally better to use GCD rather than threads and secondary run loops. And if you do need a manually-maintained thread, it's probably for something that doesn't need a run loop.
It is possible to use CFRunLoopRun recursively on an existing run loop. It's a bit more common to use CFRunLoopRunInMode instead, but in either case it's usually a sign that someone is trying to turn an asynchronous operation into a synchronous operation by pumping the run loop until the operation completes. This is fairly dangerous and can cause very strange side-effects. I've used it before, but it's kind of like swizzling; when it bites you, the bugs are mind-bending.
You're doing well. There's not problem to use CoreFoundation when you cannot achieve your goal with Foundation. As CoreFoundation is C, it's easier to mess up with memory management but there is no intrinsic danger in using rather than CFRunLoop (sometimes it may even be safer: NSRunLoop API are thread-safe whereas CFRunLoop isn't).NSRunLoop
If you want to stop your , you can run it using NSRunLoop. runMode:beforeDate: returns as soon as an input source is processed so you don't need to wait until the timeout date is reached.runMode:beforeDate:
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
NSDate *date = [NSDate distantFuture];
while ( !runLoopIsStopped && [runLoop runMode:NSDefaultRunLoopMode beforeDate:date] );
Then, to stop the run loop, you just need to set to runLoopIsStopped.YES
A Cocoa application has an implicit run loop, so just delete CFRunLoopRun();
Consider to use a dispatch queue via Grand Central Dispatch (GCD) rather than schedule the stream on a run loop
Communication between threads is a very commong problem and there is a lot of possible solutions.
One solution I see is not using but instead creating a performSelectorInBackground: instance, save the thread reference and call NSThread. Then you can use one of the start methods to call the stop method (don't forget to actually cancel the request before stopping the loop).[NSObject performSelector:onThread:...]
Another solution could be to call with a timeout inside a CFRunLoopRun cycle, waiting for some condition to happen. See the answer in iPhone: how to use performSelector:onThread:withObject:waitUntilDone: method?.while
Another solution is to use local notifications (). The background thread can register itself for notification and the main thread can send them when a condition happens.NSNotificationCenter