2013-02-20 83 views
2

我使用NSOperation和NSOperationQueue(用於2D遊戲)在後臺加載圖像。NSOperationQueue阻止無關的NSOperationQueue?

要了解如何NSOperations行爲,我已經試過加入以下無關NSOperationQueue /的NSOperation(我稱之爲-startNewEndlessBackgroundTask方式在開始任何圖像加載前):

static int stop = NO; 
static int c = 1000; 
-(void)takeTime { 
    stop = NO; 
    while (!stop) { 
     for (int i = 0; i < 10000; i++) { 
      c += 1; 
     } 
     c = c; 
    } 
} 
-(void)stopBackgroundTask { 
    stop = YES; 
} 
-(void)startNewEndlessBackgroundTask { 
    //[self performSelectorInBackground:@selector(takeTime) withObject:nil]; 
    NSOperationQueue* queue = [[NSOperationQueue alloc] init]; 
    [queue addOperationWithBlock:^{ 
     [self takeTime]; 
    }]; 
} 

這完全阻斷了我的其他NSOperationQueue的圖像加載在iPhone4上。在iPhone4s上,2次調用startNewEndlessBackgroundTask後,它會阻止我的圖像加載。兩者都運行iOS 6.

我的應用程序的主循環未被阻止。

如果我改用performSelectorInBackground來調用takeTime,一切正常,沒有阻塞,並且takeTime例程在後臺也能正常工作。

爲什麼會發生這種情況,當兩個NSOperationQueue完全分開分配並且沒有依賴關係?對我來說,以這種簡單的方式使用NSOperationQueue和使用performSelectorInBackground應該沒有什麼區別,但是我猜這是我誤解的基本原理嗎?

回答

0

不知道的細節,但這是什麼,我認爲現在正在發生的事情了部分答案..

的NSOperation使用GCD之下(因爲OSX和iOS的最後幾個版本至少)。 GCD中有一些全球優先級隊列。

當優先級較高的隊列中存在任務時,優先級較低的隊列中的任務甚至不會啓動(儘管同一全局優先級隊列中的任務可以啓動,因爲儘管名稱中有「隊列」,但任務默認優先隊列可以併發)。

由於我沒有指定任何線程優先級,我想我的-takeTime操作正在計劃在默認優先級隊列上,並且我的映像加載操作正在默認的低優先級隊列上進行調度。這可以解釋爲什麼-takeTime操作阻止了我的圖像加載。

這並沒有真正解釋這是爲什麼它需要兩個-takeTime操作來阻止我的iPhone 4s上的圖像加載操作,因爲低優先級隊列中等待高優先級隊列中任務的任務未被提及取決於CPU內核的數量 - 就我在文檔中看到的那樣。

Apple - Dispatch Queues: 「除了獲取默認併發隊列,您還可以通過在DISPATCH_QUEUE_PRIORITY_HIGH和DISPATCH_QUEUE_PRIORITY_LOW常量傳遞給函數,而不是獲得與高和低優先級隊列,或者通過將得到一個背景隊列DISPATCH_QUEUE_PRIORITY_BACKGROUND這個常量,正如你所期望的那樣,高優先級併發隊列中的任務在默認隊列和低優先級隊列中的任務之前執行,類似地,默認隊列中的任務執行在低優先級隊列中的任務之前。