2017-02-27 23 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