2017-02-27 77 views
0

我问自己一个问题,但没有答案了,所以我希望你可以有一个:调用performSelector的结果:在“睡眠”线程的当前运行循环中?

如果是具有NSThread发生了什么事他目前NSRunLoop(命名为runLoop1例如)在“睡眠”状态(当然, runLoop1调用[NSThread sleepForTimeInterval:/*...*/]),而其他NSThread调用[self performSelector:@selector(selector:) onThread:runLoop1 withObject:nil waitUntilDone:NO]

我希望我是可以理解的^^

+0

'sleepForTimeInterval'完全阻止该线程。正如[文档](https://developer.apple.com/reference/foundation/thread/1413673-sleep)所述,“线程被阻塞时不会发生运行循环处理。”出于这个原因,你很少想在生产代码中使用'sleepForTimeInterval'。 – Rob

回答

1

的runloop可以作为一个无限循环地解释:

while(!exit) { 
    // Do stuff here 
} 

这运行在一个线程,该线程处于睡眠那就这样是循环并且没有事件会被调用。

,那么什么是performSelector方法:

想象有调用的与循环将被执行时,适当的数组。由于有延迟后执行选择器的方法,所以还有一个时间戳。

while(!exit) { 
    NSMutableArray *notExecuted = [NSMutableArray new]; 
    for(Executable *item in [self.pendingExecutables copy]) { 
     if(item.executionDate && [item.executionDate compare:[NSDate date]] == NSOrderedDescending) { 
      [notExecuted addObject:item]; 
     } 
     else { 
      [item execute]; 
     } 
    } 
    self.pendingExecutables = notExecuted; 
} 

所以叫performSelector确实只是增加了执行成一些阵列所需的数据。 runloop必须正在运行,以便执行实际发生。所以在你的情况下没有任何反应,选择器将不会执行,因为整个线程正在休眠,因此循环未执行。

那么您还可以理解,如果你阻塞主线程会发生什么。没有触摸事件,没有系统通知,没有任何东西。它全部保存在数组中,一旦线程解除阻塞并发生另一个循环,它将被调用。主循环还会在每个循环中发送日期,然后用于看门狗。由于操作系统在另一个线程上工作,那么你的应用程序就是检查该日期的操作系统,如果它比较旧,你会进入“应用程序无响应”状态。然后操作系统可能会决定杀死你的应用程序。

注意,这是过于简单化,但它足以让这些东西是如何工作的一个基本的了解。

+0

感谢您的回答。在目标线程睡眠期间跳过事件发生了什么?它们在线程清醒或忽略时处理? – N0un

+0

只要线程有运行循环,线程就会被唤醒。如果调用线程与正在执行的线程相同,则可能有一种方法可以跳过它。你有没有发生这种情况? –

+0

不是特别的,但是因为我正在处理这些对象,所以我想知道。 – N0un