2011-03-10 24 views
1

我有被分派到串行隊列幾個任務,特別是一些被分派到一個組。完成這些任務後,我想讓用戶選擇取消它們,即使它們已經被執行。iPhone - 取消排隊的操作GCD

我找不到任何方法來取消排隊的任務,然後我想到我可以創建一個布爾標誌,例如調用quitRender並測試以查看該標誌是否爲true並退出渲染,但這不起作用,我的解釋是:當任務被觸發時,flagsRenderRender是NO,因此當它們在塊中執行並且塊凍結它們的值時,它們就像它們在啓動時那樣凍結,塊將不會看到更改並且永遠不會退出。

然後我嘗試另一種方法:我創建像

- (BOOL) cancelRender { 
    return quitRender; 
} 

的方法,將運行併發送塊中的變量的當前值,但顯然塊繼續看到NO的quitRender。

我錯過了什麼嗎?如何做這項工作?

謝謝。

回答

4

__block存儲修改器在這種情況下可能會有幫助。

__block BOOL quitRender = NO; 

它使得能夠修改變量從塊和塊可以看到修改後的變量。但要小心,訪問__block變量不是線程安全的。

atomic functions是優選的,以確保訪問一個變量作爲原子。

此外,你可以使用塊從伊娃。如果該變量是一個具有atomic屬性的屬性,則它對於訪問是線程安全的。

你如何使用quitRender變量?

編輯

__block int32_t quitRender = 0; 

/* set */ 
OSAtomicOr32(1, &quitRender); 

/* test */ 
if (quitRender) { 
+0

你能把這個代碼翻譯成你所謂的「原子功能」嗎? – SpaceDog

+0

我加了一個原子函數的例子。 –

+0

哇!這非常明顯!我想這是線程安全的,對吧?感謝分享! – SpaceDog

0

如果你想退出給定類的所有任務,你可以嘗試使quitRender標誌揮發性靜態BOOL全局變量,該塊代碼不應該凍結。

您可以環繞靜態全局變量的getter和setter使代碼更乾淨。

+0

你能把這個翻譯成代碼嗎? – SpaceDog

1

你是正確的軌道使得quitRender變量__block存儲類變量上,從此代碼的主體可以修改它表明掛起操作應該取消。

沒有與製作,它是線程安全的,但是正如其他人的建議,因爲取消是天生racey開始,沒有問題。您可以在將變量設置爲TRUE之前立即開始執行該塊(並執行取消檢查),在這種情況下,即使您正在執行包裝,您也會失去競賽,因此您可以設置它並忘記因爲在這種情況下取​​消標誌只能從FALSE移到TRUE狀態。

如果管理塊級存儲是出於某種原因的疼痛(說你有多個操作所有可能取消),然後把裏面的任何數據結構由隊列管理的解除標誌,只是檢查。如果隊列本身是指示隊列上的所有操作都被取消的正確位置,那麼您也可以使用dispatch_{set,get}_specific()將其與隊列本身一起存儲。 HTH。