我需要进行一系列网址调用(获取WMS图块)。我想使用LIFO堆栈,因此最新的url调用是最重要的。我想现在在屏幕上显示瓷砖,而不是5秒前平底锅上显示的瓷砖。
我可以从NSMutableArray创建自己的堆栈,但我想知道NSOperationQueue是否可以用作LIFO堆栈?
答案 0 :(得分:4)
您可以使用-[NSOperation setQueuePriority:]
设置操作队列中的操作优先级。每次添加操作时,您都必须重新调整现有操作的优先级,但是您可以实现类似于您正在寻找的操作。你基本上将所有旧的降级并给予最新的优先级。
答案 1 :(得分:3)
可悲的是,我认为NSOperationQueue
,顾名思义,只能用作队列 - 而不是堆栈。为了避免必须完成一大堆手动编组任务,可能最简单的方法是将队列视为不可变并通过复制进行变异处理。 E.g。
- (NSOperationQueue *)addOperation:(NSOperation *)operation toHeadOfQueue:(NSOperationQueue *)queue
{
// suspending a queue prevents it from issuing new operations; it doesn't
// pause any already ongoing operations. So we do this to prevent a race
// condition as we copy operations from the queue
queue.suspended = YES;
// create a new queue
NSOperationQueue *mutatedQueue = [[NSOperationQueue alloc] init];
// add the new operation at the head
[mutatedQueue addOperation:operation];
// copy in all the preexisting operations that haven't yet started
for(NSOperation *operation in [queue operations])
{
if(!operation.isExecuting)
[mutatedQueue addOperation:operation];
}
// the caller should now ensure the original queue is disposed of...
}
/* ... elsewhere ... */
NSOperationQueue *newQueue = [self addOperation:newOperation toHeadOfQueue:operationQueue];
[operationQueue release];
operationQueue = newQueue;
目前看来,释放仍在工作的队列(将发生在旧操作队列中)不会导致它取消所有操作,但这不是记录的行为,因此可能不值得信任。如果你想要非常安全,键值会观察旧队列上的operationCount
属性,并在它变为零时释放它。
答案 2 :(得分:1)
我不确定你是否还在寻找解决方案,但是我遇到同样的问题一直困扰着我,所以我继续在这里实施了一个操作堆栈:https://github.com/cbrauchli/CBOperationStack。我已经使用它进行了几百次下载操作,并且它保持良好状态。
答案 3 :(得分:1)
可悲的是,如果不遇到一些棘手的问题,你就不能这样做,因为:
重要在运行操作或将操作添加到操作队列之前,应始终配置依赖项。之后添加的依赖项可能无法阻止给定的操作对象运行。 (来自:Concurrency Programming Guide: Configuring Interoperation Dependencies)
答案 4 :(得分:0)
在NSOperationQueue之上找到了一个巧妙的堆栈/ LIFO功能实现。它可以用作扩展NSOperationQueue或NSOperationQueue LIFO子类的类别。