简体   繁体   English

NSOperationQueue阻止了不相关的NSOperationQueue?

[英]NSOperationQueue blocking unrelated NSOperationQueue?

I'm loading an image in the background using NSOperation and NSOperationQueue (for a 2d game). 我正在使用NSOperation和NSOperationQueue(对于2D游戏)在后台加载图像。

To understand how NSOperations behaves, I've tried adding the following unrelated NSOperationQueue / NSOperation (I call -startNewEndlessBackgroundTask way before starting any image loading): 为了理解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];
    }];
}

This completely blocks my other NSOperationQueue for image loading on an iPhone4. 这完全阻塞了我的其他NSOperationQueue,无法在iPhone4上加载图像。 On iPhone4s, it blocks my image loading after 2 calls to startNewEndlessBackgroundTask. 在iPhone4s上,它在两次调用startNewEndlessBackgroundTask之后阻止了我的图像加载。 Both are running iOS 6. 两者都在运行iOS 6。

The main loop of my app is not blocked. 我的应用程序的主循环未被阻止。

If I instead use performSelectorInBackground to invoke takeTime, everything works fine with no blocking, and the takeTime routine working properly in the background as well. 如果我改为使用performSelectorInBackground来调用takeTime,则一切正常,没有阻塞,并且takeTime例程在后台也正常运行。

Why could this be happening, when the two NSOperationQueue's are alloc-init'ted completely separately and have no dependencies? 当两个NSOperationQueue分别完全初始化分配并且没有依赖关系时,为什么会发生这种情况? To me, there shouldn't be a difference between using an NSOperationQueue in this simple way, and using performSelectorInBackground, but I guess there is something fundamental that I am misunderstanding? 对我来说,以这种简单的方式使用NSOperationQueue与使用performSelectorInBackground之间应该没有区别,但是我想我有一些基本误解吗?

Not sure about the details, but this is a partial answer for what I now think is happening.. 不确定细节,但这只是我现在认为正在发生的事情的部分答案。

NSOperation uses GCD underneath (at least since the last few versions of OSX and iOS). NSOperation在下面使用GCD(至少从OSX和iOS的最后几个版本开始)。 There are certain global priority queues in GCD. GCD中有某些全局优先级队列。

When there is a task in a higher priority queue, tasks in the lower priority queues are not even started (though tasks in the same global priority queue can start, since despite having "queue" in their name, tasks in a default priority queue can be concurrent). 当高优先级队列中有任务时,低优先级队列中的任务甚至都不会启动(尽管同一全局优先级队列中的任务可以启动,因为尽管名称中有“ queue”,但默认优先级队列中的任务仍可以启动)并发)。

Since I don't specify any thread priority, I imagine my -takeTime operation was being scheduled on the default priority queue, and my image loading operation was being scheduled on the default low priority queue. 由于我没有指定任何线程优先级,因此我想将-takeTime操作安排在默认优先级队列中,并将图像加载操作安排在默认低优先级队列中。 This would explain why the -takeTime operation was blocking my image loading. 这可以解释为什么-takeTime操作阻止了我的图像加载。

What this doesn't really explain, is why it would take two -takeTime operations to block my image loading operation on an iPhone 4s, since tasks in low priority queues waiting for tasks in high priority queues isn't mentioned to be contingent on the number of CPU cores - as far as I've seen in the docs. 这并没有真正解释的原因是为什么要花两个-takeTime操作来阻止我在iPhone 4s上的图像加载操作,因为低优先级队列中的任务没有等待高优先级队列中的任务,这取决于CPU核数-据我在文档中所见。

Apple - Dispatch Queues : "In addition to getting the default concurrent queue, you can also get queues with high- and low-priority levels by passing in the DISPATCH_QUEUE_PRIORITY_HIGH and DISPATCH_QUEUE_PRIORITY_LOW constants to the function instead, or get a background queue by passing the DISPATCH_QUEUE_PRIORITY_BACKGROUND constant. As you might expect, tasks in the high-priority concurrent queue execute before those in the default and low-priority queues. Similarly, tasks in the default queue execute before those in the low-priority queue." Apple-Dispatch Queues :“除了获取默认的并发队列之外,您还可以通过将DISPATCH_QUEUE_PRIORITY_HIGH和DISPATCH_QUEUE_PRIORITY_LOW常量传递给函数来获取具有高优先级和低优先级级别的队列,或者通过将DISPATCH_QUEUE_PRIORITY_BACKGROUND传递给后台队列如您所料,高优先级并发队列中的任务先于默认队列和低优先级队列中的任务执行。类似地,默认队列中的任务先于低优先级队列中的任务执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM