2009-07-14 94 views

回答

43

每個程序至少運行一個線程。您可以將每個線程看作是一個獨立的程序執行過程,每個過程與其他過程並行進行。

如果您有某種用戶界面或需要監聽事件的其他代碼(如網絡端口),則需要運行循環。每個NSThread自動獲得自己的運行循環,而且你很少直接關心它們。運行循環也負責創建和釋放自動釋放池。

[編輯:查看關於autorelease池的更多討論的評論。要記住的最重要的一點是新線程必須注意設置自動釋放池。例如,被調用時detachNewThreadSelector(見下文)的方法應具有以下作爲第一行和最後一行:

NSAutoreleasePool *pool = [ [ NSAutoreleasePool alloc ] init ]; 
    [code here] 
    [pool release]; 

這同樣適用於線程使用其他技術產生了]

主線程,其中所有UI處理正在發生,運行循環非常重要,因爲它使接口保持反應。這就是爲什麼你永遠不應該在主線程上運行耗費時間的代碼:它會在線程中耗盡所有時間,並且運行循環將不被允許運行得足夠頻繁,從而導致鎖定或緩慢的接口。如果您需要執行耗時的計算,或者讓任務在後臺運行,則應該創建一個新線程。同樣,您可能不必考慮正在創建的新運行循環。在一個新的線程中執行方法的一個簡單的方法:

[NSThread detachNewThreadSelector:@selector(theSelector) toTarget:self withObject:nil]; 

線程間的通信可能會非常棘手,你應該知道的方法performSelector:onThread:withObject:waitUntilDone:performSelectorOnMainThread:withObject:waitUntilDone: (跨線程here發送NSNotifications大的提示。)

定時器也由運行循環處理。與運行循環相反,您可能經常直接在您的程序中使用計時器。創建一個計時器的非常簡單的方法是:

[self performSelector:@selector(aSelector) withObject:nil afterDelay:1.0]; 

,但有時你要創建和管理的NSTimer對象自己,例如能夠取消並重新使用定時器。

An NSTask用於運行另一個程序作爲當前子程序的子進程。這與啓動一個單獨的線程有些相似,但是如果子進程崩潰,那麼主程序將繼續運行。程序之間的通信也與同一進程中多個線程之間的通信非常不同。

你用「iphone」標記了你的問題,而在iPhone上你永遠不會使用NSTasks。當你需要處理的不同任務的大量

NSOperations使用,將它們放置在隊列和/或在單獨的線程處理它們(雖然他們不在單獨的線程中運行)。如果您的應用程序需要創建少數專用線程,那麼沒有理由使用NSOperation類。但是,如果您經常會生成必須跟蹤的任務(如與服務器通信),則NSOperation和NSOperationQueue將派上用場。

+0

「運行循環也負責創建和釋放自動釋放池。」關閉。 NSApplication這樣做(在主線程上),而不是NSRunLoop。如果你生成自己的線程,你必須創建自己的池。(我引用了NSAutoreleasePool文檔:「NSAutoreleasePool對象在基於應用程序工具包的應用程序的主線程中自動創建和銷燬......」) – 2009-07-14 10:07:31

+0

我認爲你們都錯了。如果您查看樣板main.m文件,* this *是創建和管理NSAutoreleasePool的位置。在我看來,runloop和autoreleasepool之間沒有任何關聯。 – Lounges 2009-07-14 18:02:26

4
  • NSTimer是一個計時器對象,是一種在將來調用對象選擇器的方法。
  • NSThread是一個線程類。我想你知道一個線程是什麼。
  • NSTask是一個進程類,用於從程序運行另一個程序。
  • NSOperation(我加入這個問題)對於單個任務來說是一個很好的抽象。您可以在此課程中嵌入您的操作,並且您可以通過NSOperationQueue課程輕鬆地同時執行。
  • NSRunLoop是最難理解的。以某種方式抽象和調整了unix系統調用,管理輸入源以及調度線程上的事件和計時器。

準則是Apple Threading Programming Guide

3

其他答案在總結定時器,任務和線程方面做得相當不錯。我想對NSRunloop做更多的評論,因爲我認爲大多數其他答案在這裏仍然存在一些困惑。從NSRunloop文檔:

一個NSRunLoop對象處理用於源,例如鼠標和鍵盤從窗口系統 事件,NSPORT 對象和對象NSConnection連接輸入 。一個 NSRunLoop對象也處理 NSTimer事件。

一般情況下,你的應用程序不 需要創建或明確 管理NSRunLoop對象。每個 NSThread對象(包括 應用程序的主線程)都有一個 NSRunLoop對象,根據需要自動創建 。如果您需要 訪問當前線程的運行循環,您可以使用類方法 currentRunLoop執行 。

將NSRunloop看作是特定線程的主要事件處理和調度循環。它從輸入設備讀取數據,爲需要服務的任何對象提供服務,並適當地分配數據。

相關問題