2013-02-20 79 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这个常量,正如你所期望的那样,高优先级并发队列中的任务在默认队列和低优先级队列中的任务之前执行,类似地,默认队列中的任务执行在低优先级队列中的任务之前。