两个同时使用NSOperationQueue的后台任务

我有两个任务需要在不同的线程优先级中同时执行:

  1. 不断地收集和处理陀螺仪运动数据(高优先级)

    gyroQueue = [[NSOperationQueue alloc] init]; [self.motionManager startDeviceMotionUpdatesToQueue:gyroQueue withHandler:^(CMDeviceMotion *motion, NSError *error){ [self processMotion:motion withError:error]; }]; 
  2. 有时在不干扰运动更新的情况下处理图像(转换,裁剪,分割等= 1-2秒)(非常低的优先级)

     imageProcessingQueue = [[NSOperationQueue alloc] init]; [imageProcessingQueue addOperationWithBlock:^{ [self processImage:[UIImage imageWithData:imageData]]; }]; 

编辑:这是我原来的地方(而不是块操作),它仍然阻止运动更新:

 NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(processImage:) object:[UIImage imageWithData:imageData]]; [operation setThreadPriority:0.0]; [operation setQueuePriority:0.0]; [imageProcessingQueue addOperation:operation]; 

看起来这两个任务都在同一个后台线程上执行(由于NSOperationQueue性质?),并且处理图像会阻塞陀螺队列更新直到完成,这就是我想要避免的。

我如何使用NSOperationQueue产生两个单独的线程,并相应地分配非常高和非常低的优先级?

编辑:这个问题仍然是开放的,我正在使用特劳沃哈蒙的图像resizefunction的图像resize。 有人可以确认它是否线程安全?

我想在这里你可以尝试创build一个操作队列,并尝试根据你的需要设置每个操作的优先级。 如果只使用一个队列,线程的优先级将会更加有效,让你的思路更加清晰(毕竟这只是build议)。

 - (void)setThreadPriority:(double)priority 

您指定的值将映射到操作系统的优先级值。 指定的线程优先级只在操作的主要方法执行时才应用于线程。 当操作的完成块正在执行时,它不应用。 对于创build自己的线程的并发操作,必须在自定义启动方法中自行设置线程优先级,并在操作完成时重置原始优先级。

从苹果的文件。

Operation queues usually provide the threads used to run their operations. In Mac OS X v10.6 and later, operation queues use the libdispatch library (also known as Grand Central Dispatch) to initiate the execution of their operations. As a result, operations are always executed on a separate thread, regardless of whether they are designated as concurrent or non-concurrent operations. In iOS 4 and later, operation queues use Grand Central Dispatch to execute operations.

我发现这个问题的一个解决scheme(或坚实的解决方法):

而不是使用startDeviceMotionUpdatesToQueue将deviceMotion更新路由到队列,我已经创build了一个CADisplayLink计时器,并且不会干扰其他背景队列 – 当它与屏幕刷新率相匹配时,它的性质是最高优先级:

 [self.motionManager startDeviceMotionUpdates]; gyroTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(processMotion)]; [gyroTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];