2012-03-03 70 views
10

我在後臺使用dispatch_async運行一堆物品,有時候我想殺掉隊列中的物品 - 這可能嗎?例如,此代碼在視圖上運行,然後用戶返回一個屏幕。無論後退導航如何,所有這些已啓動的操作都會繼續運行。理想情況下,我想從運行殺死這些項目:在iOS的dispatch_async隊列中殺死物品

dispatch_async(dispatch_get_global_queue(2, 0), ^{ 
     for (int i=0; i<[self.manufacturers count]; i++) { 
      NSString *manufacturerID = [[[self.manufacturers objectAtIndex:i] ManufacturerID] stringValue]; 
      [self doSync:manufacturerID withIndex:i setTimer:YES]; 
     } 
    }); 

如果我創建一個隊列,並將它命名,然後再釋放這個被稱爲他們仍然繼續運行視圖的dealloc的。

回答

14

在調度隊列中沒有明確規定終止。爲了做到這一點,測試逃生地點以確定終止是有點常見的。基本上,這將是一個信號量。

NSOperationQueue(更高層次的抽象,但仍然使用下面的GCD構建)確實支持取消操作。因此,例如,您可以創建一系列NSOperations,並將它們添加到NSOperationQueue,然後在不需要它完成時將消息-cancelAllOperations添加到隊列中。

您選擇的體系結構很多將取決於其中有多少個正在運行以及它們是否具有不同的觸發器。在這些實現中,NSOperation可能是「最乾淨的」解決方案,因爲您有一個任意隊列,您可以觀察操作完成,還可以取消未完成的操作。進一步降低黑客的規模將是一個易變的位置,每個這些塊在緊密的循環內觀看,以確定它們是否會過早完成。對於相同的基本功能,更進一步的下降將是一個全局變量。最後,甚至NSOperation的實現都涉及到一個測試,以便在一個一致的位置退出(因爲只是殺死一個線程可能會導致數據在分配/再訓練時不一致)。

2

執行此操作的最佳方法是創建您自己的併發隊列(不使用全局隊列之一),然後在隊列中調用dispatch_suspend()以便在其中停止處理。在這一點上閱讀:Dispatch queues: How to tell if they're running and how to stop them

使用取消標誌將讓你然後恢復隊列,使所有剩餘的塊基本上只是退出(在做任何內存管理他們需要做的事情,如釋放資源),當你恢復它再次。您也可以在恢復後立即將dispatch_release()隊列。