使用NSOperationQueue作为LIFO堆栈?

时间:2012-04-09 19:24:12

标签: objective-c ios nsoperationqueue

我需要进行一系列网址调用(获取WMS图块)。我想使用LIFO堆栈,因此最新的url调用是最重要的。我想现在在屏幕上显示瓷砖,而不是5秒前平底锅上显示的瓷砖。

我可以从NSMutableArray创建自己的堆栈,但我想知道NSOperationQueue是否可以用作LIFO堆栈?

5 个答案:

答案 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

看看这个相关的问题:AFURLConnectionOperation 'start' method gets called before it is ready and never gets called again afterwards

答案 4 :(得分:0)

在NSOperationQueue之上找到了一个巧妙的堆栈/ LIFO功能实现。它可以用作扩展NSOperationQueue或NSOperationQueue LIFO子类的类别。

https://github.com/nicklockwood/NSOperationStack