在继续阅读文档之前,我的大脑在这一点上陷入困境:
- (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
}
我在代码示例中添加了一些注释。也许有人可以解释这一点,为什么有一个while循环,如果有一个runLoop对象接收-runUntilDate:消息。我的意思是:这里的循环是谁?我看到两个。首先,这显然是一个运行循环,然后它调用一个听起来像运行循环井的方法。
stateConfused = YES;
pleaseExplain = YES;
答案 0 :(得分:1)
从技术上讲,NSRunLoop
在内部循环(它循环“直到日期”)。这为您提供了一个定期退出线程的机会 - 如果您使用run
而不是runUntilDate:
,那么NSRunLoop
将永远在内部循环(您不需要在一段时间内将其包裹起来循环但你永远不能阻止它)。这是主线程的正常行为,而不是通常具有需要定期检查的退出条件的工作线程。
runLoop
永远不会更改moreWorkToDo
或exitNow
的值(当线程的工作完成或用户退出您的应用程序时,您负责执行此操作)但这些是你如何决定是否要让线程终止。
根据您希望线程的行为方式,您可以将这些标记替换为[NSApp isRunning]
和[tasksRemainingForThisThreadToProcess count] != 0
或类似标记。
(竞争条件警告:如果在处理完所有剩余任务时结束线程,请注意在tasksRemainingForThisThreadToProcess
为空时永远不要向线程发送另一个任务,因为这表示该线程将退出)
答案 1 :(得分:0)
一个是负责维护运行循环状态的对象,另一个是实际循环。
答案 2 :(得分:0)
第一个是实际的runloop,[NSRunLoop currentRunLoop]
返回的runloop是由UIApplication创建的。简化后,它会接收所有操作系统事件(键盘,鼠标等)并将它们发送到您的程序。如果您致电[runLoop runUntilDate:[NSDate date]];
,这将在指定日期过后返回,但您的程序将继续接收操作系统事件。请参阅此link。
这与调用:
不同[[NSThread currentThread] sleepFormTimeInterval:]
,它会让你的线程完全进入睡眠状态,甚至不会收到操作系统事件。