2009-10-03 52 views
6

我正在使用一些代碼來處理各種回調的異步操作; Snow Leopard使用塊和GCD使這非常容易。NSOperationQueue在Snow Leopard上的輕量級?

我從NSBlockOperation像這樣叫NSTask

[self.queue addOperationWithBlock:^{ 
    NSTask *task = [NSTask new]; 
    NSPipe *newPipe = [NSPipe new]; 
    NSFileHandle *readHandle = [newPipe fileHandleForReading]; 
    NSData *inData = nil; 
    [task setLaunchPath:path]; 
    [task setArguments:arguments]; 
    [task launch]; 

    while ((inData = [readHandle availableData]) && [inData length]) { 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
      // callback 
     }]; 
    } 

    [task waitUntilExit]; 
}]; 

這種方法完美的作品。這就像魔術一樣,只要我的回調正確處理併發。

現在,我希望能夠合併這些呼叫中的一部分;這是在模型對象的「刷新」方法中,可能需要很長時間才能完成。讓用戶敲擊刷新按鈕不應該捆綁機器等等。

我可以在這裏看到執行困境。我可以創建一大堆隊列 - 每個呼叫類型 - 並將其併發操作計數設置爲1,然後每當需要新呼叫時撥打-cancelAllOperations。或者,我可以做一些更多的手動簿記,目前正在調用哪些調用,併爲每個模型對象管理單個隊列(如我所做的那樣),或者我可以更進一步並使用全局隊列。

NSOperationQueue有多重?是否創建了很多排隊糟糕的架構決策?有沒有更好的方法來合併這些任務?

+2

僅供參考,您正在泄漏您的NSTask和您的NSPipe。 + new相當於+ alloc/-init,這意味着你有責任釋放它們......你永遠不會做(在你的代碼中)。 (當然,除非你使用GC) – 2009-10-03 15:58:07

+1

這是一個僅限雪豹的程序。我當然希望你的全新Snow-Leopard-only代碼是垃圾收集的。 :-D – 2009-10-03 22:52:29

回答

8

如果您關注性能,請不要猜測:測量並修復找到的瓶頸。添加隊列很簡單;試試看看Instruments告訴你關於性能的影響。

創建多個隊列的主要原因是如果您有某些原因希望啓動和停止它們。如果您只想獲得libdispatch的好處,只需將操作添加到主隊列即可獲得。

0

只要你喜歡使用盡可能多的操作隊列。他們在這裏分開你的程序的邏輯部分。只要你沒有每秒分配數百個隊列,我認爲你不應該太在意性能。

+0

網站?這與網站有什麼關係? – 2009-10-03 08:34:19

+0

謝謝,早上還爲時過早。 :) – 2009-10-03 09:06:36

1

您可以將多個塊 添加到NSBlockOperation中,該塊將被同時執行並且可以被取消 取消包含操作。只要你的個人任務不需要序列化,這可能工作。

+0

這不是文檔所說的:「NSBlockOperation類是NSOperation的一個具體子類,它管理一個或多個塊的併發執行。」 http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/NSBlockOperation_class/Reference/Reference.html – 2009-10-03 22:57:24

+0

吉姆,你絕對正確。答案已更新。謝謝。 – 2009-10-04 04:01:36