2013-05-10 128 views
5

我讀了很多關於NSRunLoop的帖子,如this,this,this。但不能找出NSRunLoop實際上做NSRunLoop做什麼?

我通常看到的是一個工作線程

wthread = [[NSThread alloc] initWithTarget:self selector:@selector(threadProc) object:nil]; 
[wthread start]; 

與NSRunLoop裏面

- (void)threadProc 
{ 
    NSAutoreleasePool* pool1 = [[NSAutoreleasePool alloc] init]; 
    BOOL isStopped = NO; 
    NSRunLoop *runloop = [NSRunLoop currentRunLoop]; 
    [runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; 

    while (!isStopped) 
    { 
     { 
      NSAutoreleasePool* pool2 = [[NSAutoreleasePool alloc] init]; 
      [runloop runMode:NSDefaultRunLoopMode 
             beforeDate:[NSDate distantFuture]]; 

      [pool2 release]; 
     } 
    } 

    [pool1 release]; 
} 

和主線程通過一些工作,這線程

[self performSelector:@selector(someWork:) onThread:wthread withObject:nil waitUntilDone:NO]; 

在將工作從主線程傳遞給工作我看到許多人這樣做。爲什麼需要NSRunLoop?它有什麼作用 ?

我看過NSRunLoop是用來管理事件的,爲什麼除了調用runModethreadProc之內呢?

+0

我認爲它是一個幻想,而(真){//插入要在這裏完成的工作},其中你可以動態添加要執行的代碼(事件,工作,套接字等)。 runloop不是真的是空的,一個端口已經連接到runloop,它是進程間通信的一種形式。 – foFox 2013-05-10 07:56:00

+0

我發現這個http://bou.io/RunRunLoopRun.html也是有用的 – onmyway133 2015-06-17 17:17:44

回答

3

您展示的示例是一個Cocoa成語,用於創建一個線程,該線程將在方法-threadProc退出後繼續運行。爲什麼?

因爲:

  • 你所創建的NSRunLoop實例已至少一個輸入源([NSMachPort port]
  • 你已經明確開始與runMode:beforeDate

運行循環而不添加輸入源並顯式啓動運行循環,線程將終止。儘管運行循環對於管理事件和某些異步任務仍然至關重要,但我不認爲NSThread是當今Cocoa應用程序中構建大多數異步工作的默認方式。 GCD是封裝後臺工作的更簡潔的方式。

編輯

在GCD提交工作提高到一個串行隊列:

@interface Foo : NSObject 
@end 

@implementation Foo { 
    dispatch_queue_t _someWorkerQueue; 
} 

- (id)init { 
    self = [super init]; 
    if(!self) return nil; 

    _someWorkerQueue = dispatch_queue_create("com.company.MyWorkerQueue", 0); 
    return self; 
} 

- (void)performJob { 
    dispatch_async(_someWorkerQueue, ^{ 
     //do some work asynchronously here 
    }); 

    dispatch_async(_someWorkerQueue, ^{ 
     //more asynchronous work here 
    }); 
} 
@end 
+0

1)那爲什麼threadProc裏面有while循環呢? 2)GCD將把工作轉移到任何可用/未知的線程,但NSRunLoop將確保所有工作都將轉移到同一個工作線程,對嗎? – onmyway133 2013-05-12 00:57:47

+0

提供終止運行循環的機制 - 當設置'isStopped'標誌時(儘管這在代碼中沒有顯示出來......) – FluffulousChimp 2013-05-12 09:09:12

+0

2)請參閱針對您所描述的用例的GCD方法的編輯答案。 – FluffulousChimp 2013-05-12 09:22:05

3

很多事情都在幕後發生。這是因爲它提供了一種方式讓線程在沒有工作項時停止執行。如果您曾經使用過實時操作系統,那麼任務需要一個放棄處理器的地方,以便其他人可以運行。

沒有很好的記錄是,當你發送performSelector:onThread:...時,它是運行循環,將消息排隊並喚醒以讓線程處理它。如果您將日誌消息添加到while循環中,您可以看到發生這種情況。

對於真正好奇的是github上有示例代碼,您可以使用循環運行 - 添加一條評論,然後列出一些代碼。

+0

1)但在threadProc中,有一個while循環,所以線程總是忙? NSRunLoop如何告訴它停止執行? 2)AFAIK,這是一個機制,以確保許多調用performSelector:onThread:將工作轉移到同一個工作線程,對吧? – onmyway133 2013-05-11 03:52:12

+0

1)抱歉,不清楚 - 操作系統將暫停runMode中的線程:如果沒有任何代碼需要處理。 2)它是系統的一個功能 - 但還有其他功能 - 端口和定時器處理。通過閱讀CFRunloop上的蘋果文檔,您將學到最多 - 我相信這有一個指南。 – 2013-05-11 11:45:17