I'm testing with run loops in standard (created by XCode) App. My App has 2 buttons:
Start Loop
- starts runloop in some mode (see code below);Stop Loop
- changeself.stop
flag to stop runloop.
`
- (IBAction)stopLoop:(id)sender
{
self.stop = YES;
}
- (IBAction)startLoop:(id)sender
{
self.stop = NO;
do
{
[[NSRunLoop currentRunLoop] runMode:runLoopMode beforeDate:runLoopLimitDate];
if (self.stop)
{
break;
}
} while (YES);
}
`
where:
1. runLoopMode
is one of the predefined modes (I try each, default, event tracking, modal, connection).
2. runLoopLimitDate
[NSDate distantFuture], or [NSDate distantPast], or close feature.
3. self.stop
flag is installed in other method, which called by button.
That's all, my App hasn't any other code.
AFAIU, runloop mode is a set of event sources. So, if I run runloop in some mode, runloop will be proceed those event sources, whose are associated with this mode.
By default Cocoa runs runloop in default mode and all events are proceeds greatly. But when user press startLoop
button, my App is freezing: .
startLoop
method is never break this infinity cycle. Application doesn't send any event to me, therefore UI freezing and user can't press stopLoop
button. The same problem if I run Core Foundation counterparts.
But, when I try to receive events through NSApplication (of NSWindow) method nextEventMatchingMask:untilDate:inMode:dequeue:
and pass the same mode, I receive UI events.
- (IBAction)startLoop:(id)sender
{
self.stop = NO;
do
{
NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES];
if (event == nil)
{
break;
}
[NSApp sendEvent:event];
if (self.stop)
{
break;
}
} while (YES);
}
There are question: "Why if I run default run loop mode, or some other, in this way, I can't receive events?"
Thanks for your advice.