2

我想利用GCD,例如,所有需要從服務器下載一些數據的一百個對象。如果我要遍歷這些對象,並調用是這樣的:iOS上的GCD可以處理數百個調度塊嗎?

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 
dispatch_async(q, ^{ 
    // Download data; 
}); 

那些會得到塊智能排隊和有效地執行,還是我碰到內存問題,性能問題,甚至是競爭條件?

我的兩個美分是,塊將按照名稱的建議排隊,並且下載將一次開始一次,並且只要我在所有下載完成之前終止應用程序就能正常清理,不成問題。

然而,另一個加分題:

我會更多地受益,如果我是創造,也就是說,3-5隊列,並通過分發下載隊列當中下載多個文件在任何一個時間?


實施此功能後,似乎接受的答案不完整,或者我錯過了這一點。因爲可以由GCD調度的最大線程數(〜64),所以在全局隊列上調度塊是一個併發的隊列,可能會導致問題。這僅適用於併發隊列,因爲它們需要爲產生一個線程,每個線程都運行。但是,如果您創建自己的隊列,那麼即使調用dispatch_async,該隊列也會依次執行塊。這樣,你可以確定你的隊列只會產生1個線程,並且排列你的操作,並且永遠不會遇到線程限制問題。

回答

4

解決你的第一個問題,即「這些塊會被智能排隊並高效執行,還是會遇到內存問題,性能問題甚至是競態條件」。

我的答案:

  1. 那些會得到塊智能排隊和有效地執行:是的,他們會毫無疑問。

  2. 我會遇到內存問題,性能問題:這是情況相關的。當你調用異步方法,所以它不會保證第二次下載操作將在第一次完成後開始。如果由於CFDATA或CFDATA(存儲)問題(可以處理)而導致圖像或視頻下陷,則可能會遇到內存不足問題。

  3. 甚至競態條件:如果您知道如何以及何時切換線程,您將永遠不會陷入競爭狀態。例如:如果您下載的類委託需要在主線程上調用,則需要像在NSURLConnection中一樣在主線程上啓動連接。如果在donwload之後處理UI元素,則仍然需要切換線程。其他方面沒有競爭條件或僵局會發生。

解決你問題的第二一堆「我會受益更多,如果我是創造,也就是說,3-5隊列,並通過分發下載隊列當中下載多個文件在任何一個時間?」

如果我將在你的地方,我會用單隊列數百個對象。我一直在這種情況下,在我的情況下,我不得不下載成千上萬的文件。我會一次下載單個文件,並進行清理,然後繼續前進。就好像您有數百個文件需要下載,即使是0.1 MB的額外分配也會導致性能問題。

+0

偉大的答案。您能否詳細說明您提到的內存問題?在你的回答中,當你提到CFData問題時,你提到了遇到內存問題的可能性,並且在最後一行,當文件只有0.1 MB時。爲什麼會這樣呢?這與CFData有什麼關係? – Mazyod

+1

當您下載圖像或視頻時,它會在您的緩存中創建CFDATA和CFDATA(存儲),並不會自動清除。它永遠不會被抓到,因爲即使緩存已滿,您的應用仍然可以訪問它。但是當你處理數百個文件/對象時,這些CFDATA在積累之後會變得非常龐大。因此,如果CFDATA在緩存中的大小爲0.1MB,那麼在下載數百個文件時將會有巨大的累積。 –

+0

當然,我會接受。關於排隊任務的最後一件事。你認爲分配一個HIGH_PRIORITY_QUEUE異步是合理的,然後使用'sync'在另一個隊列上調用這些塊以確保它們按順序執行? – Mazyod

0

在MacOS X和iOS版(O'Reilly)的並行編程:

enter image description here

相關問題