“[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distinctFuture]]”有啥作用?

Posted

技术标签:

【中文标题】“[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distinctFuture]]”有啥作用?【英文标题】:What does "[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]" do?“[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distinctFuture]]”有什么作用? 【发布时间】:2015-07-03 06:18:37 【问题描述】:

我有一些关于 NSRunLoop 的问题。当运行如下代码时,主线程似乎停止并且在while循环之后它不会运行代码。 我想知道什么时候 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distinctFuture]] 执行,在主线程的运行循环中发生了什么?众所周知,UI mainthread'runloop 在应用启动时会自动运行,主线程是休眠还是死循环?

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

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

    NSLog(@"End RunLoop");

【问题讨论】:

【参考方案1】:
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]

这行代码只是让线程执行一次循环的源代码,如果没有任务,则立即返回。所以这些代码不会阻塞你的主线程。主线程的runloop自动运行意味着主线程保持一个while循环一次又一次地执行[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]。当它遇到您自己的 while circle while (!self.runLoopThreadDidFinishFlag) 时,状态可能始终为 true,可能会阻塞线程。您自己的代码[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] 在这里意味着执行一次循环的源代码或清理运行循环的源代码中的任务,如果有一个任务更改self.runLoopThreadDidFinishFlag 那么您的代码将继续前进。

所以[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] 在你的while 圈子中让主线程有机会goto 执行其他可能会改变runLoopThreadDidFinishFlag 的代码。

PS。 [NSRunLoop run]runMode:beforeDate: 非常不同,您可能会感到困惑。 NSRunLoop apple document


编辑 20190606。main-runloop(主线程)中的 while-loop 示例代码。

您可以测试,如果“runMode:beforeDate:”函数被删除,while-loop不能被“Stop”按钮停止。所以这里的 "runMode:beforeDate:" 提供了在 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");
    

【讨论】:

你的意思是“你的while循环让主线程有机会去执行其他可能改变runLoopThreadDidFinishFlag的代码。”我认为主线程被阻塞,直到有输入源要从最终更改标志的主运行循环中处理? @slow 是的。我在原始答案中添加了一些示例代码。我将 'beforeDate' 更改为当前日期,以便我们的 while 循环正常工作并且可以随时启动和停止。

以上是关于“[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distinctFuture]]”有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章