5

I have some problem about NSRunLoop. When run the code as below,the main thread seem to stop and It wouldn't run the code after the while loop. I want to know when [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] performed, what happen in mainthread's runloop? As we know UI mainthread'runloop run automaticly when the app launched, does main thread sleep or it in a dead loop?

while (!self.runLoopThreadDidFinishFlag) {
    NSLog(@"Begin RunLoop");

    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

    NSLog(@"End RunLoop");
}
leppie
  • 115,091
  • 17
  • 196
  • 297
Slemon
  • 791
  • 7
  • 12

1 Answers1

4
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]

This line of codes just let the thread execute the loop's sources once, if there is no task, it return immediately. So these codes don't block your main thread. Mainthread's runloop run automaticly means main thread keep a while circle to execute [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] again and again. When it run into your own while circle while (!self.runLoopThreadDidFinishFlag) the status may always true that may block the thread. your own code [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] here means to execute the loop's sources once or clean tasks in the runloop's sources, if there is one task change self.runLoopThreadDidFinishFlag then your code will move on.

So [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] in your while circle make the mainthread have a chance to goto execute other code which may change the runLoopThreadDidFinishFlag.

PS. [NSRunLoop run] is very different with runMode:beforeDate: you may confused. NSRunLoop apple document


Edit 20190606. Example codes for while-loop in main-runloop(main thread).

You can test, if the "runMode:beforeDate:" function deleted, the while-loop cannot be stopped by the "Stop" button. So here "runMode:beforeDate:" gives a chance to run other codes in the out big-while-loop(main-runloop).

- (IBAction)stopMyLoop:(id)sender {
    self.runLoopThreadDidFinishFlag = YES;
    NSLog(@"stopMyLoop");
}

- (IBAction)startMyLoop:(id)sender {
    NSLog(@"startMyLoop");
    self.runLoopThreadDidFinishFlag = NO;
    while (!self.runLoopThreadDidFinishFlag) {
        NSLog(@"Begin RunLoop");
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];
        NSLog(@"End RunLoop");
    }
}
rotoava
  • 625
  • 8
  • 18
  • 1
    What do you mean by "your while circle make the mainthread have a chance to goto execute other code which may change the runLoopThreadDidFinishFlag." I thought the main thread is blocked until there's input source to handle from the main runloop that ultimately changes the flag? – slow Jun 05 '19 at 15:19
  • @slow Yes. And I add some sample codes to the origin answer. I change the 'beforeDate' as current date so our while-loop works normal and can be started and stopped at any time. – rotoava Jun 06 '19 at 04:03