NSOperationQueue:一系列具有依赖关系的 NSOperation's VS (maxConcurrentOperationCount == 1)? [英] NSOperationQueue: a sequence of NSOperation's with dependencies VS (maxConcurrentOperationCount == 1)?

本文介绍了NSOperationQueue:一系列具有依赖关系的 NSOperation's VS (maxConcurrentOperationCount == 1)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如我有 3 个对象:

For example I have 3 objects:

NSOperation *op1 = ...;
NSOperation *op2 = ...;
NSOperation *op3 = ...;

[op3 addDependency:op2];
[op2 addDependency:op1];

NSOperationQueue *queue = ...;
queue.maxConcurrentOperationCount = 1;
[queue addOperations:@[op1, op2, op3] waitUntilFinished:NO];

我可以简单地按正确顺序添加所有操作.但例如,如果 op2 被取消,那么我也应该取消 op3 并且在这种情况下我无法完全清除队列.

I could simply add all the operations in correct order. But for example if op2 is cancelled then I should also cancel op3 and I can't fully clear a queue in this case.

我的问题:

1) 将这样的操作序列与 maxConcurrentOperationCount == 1 结合起来是否安全?

1)Is it safe to combine such sequences of operations with maxConcurrentOperationCount == 1?

2) 如果我交换 op1op2,程序实际上会做什么?(op2 应该在 op1 之后执行,但队列只能同时从操作中取出一个)

2)What will the program actually do if I swap around op1 and op2? (op2 should be performed after op1 but the queue is able to take only one from the operations simultaneously)

附言在我的应用程序中,我使用 AFHTTPRequestOperation.它的继承层次:

P.S. In my application I use AFHTTPRequestOperation. Its inheritance hierarchy:

AFHTTPRequestOperation -> AFURLConnectionOperation -> NSOperation

所以我不能简单地采用 NSOperation 的其他子类.

So I can't simply take other subclass of NSOperation.

推荐答案

回答您的问题:

  1. 将此特定操作序列与您使用 maxConcurrentOperations = 1 提供的依赖项结合起来是安全的.
  2. 队列将运行op2op3op1op2op1, op3 如果将 op1op2 的依赖顺序颠倒.
  1. It's safe to combine this particular sequence of operations with the dependencies you have given with maxConcurrentOperations = 1.
  2. The queue will run op2, op3 and op1 or op2, op1, op3 if you reverse the dependency order of op1 and op2.

您指定的依赖链中没有什么棘手的,NSOperationQueue 可以自动处理这些事情.如果您指定循环依赖(例如 op3 依赖于 op1),或者您有一个未添加到队列中的操作,那么您只会遇到麻烦,并且所以无法执行以满足依赖项.

Theres nothing tricky in the dependency chain you've specified and NSOperationQueue can take care of things automatically. You can only really get into trouble if you specify a circular dependency (e.g op3 depends on op1), or you have an operation that isn't added to the queue, and so can't get executed to satisfy a dependency.

Apple 在 NSOperationQueue 中提到取消类参考:

取消操作会导致操作忽略它可能具有的任何依赖项.这种行为使队列可以尽快执行操作的 start 方法.反过来,start 方法将操作移动到完成状态,以便将其从队列中移除.

Canceling an operation causes the operation to ignore any dependencies it may have. This behavior makes it possible for the queue to execute the operation’s start method as soon as possible. The start method, in turn, moves the operation to the finished state so that it can be removed from the queue.

所有 NSOperation 子类都应该正确处理取消,首先检查它是否已被取消,然后立即完成操作而不执行任何操作.如果不这样做,那就是一个错误,即使操作被取消,操作也可能会执行.

All NSOperation subclasses should handle cancellation correctly by first checking to see if it has been cancelled and then immediately finish the operation without performing any actions. If this isn't done then it's a bug, and operations may execute even though they have been cancelled.

(有趣的是,这也适用于 NSBlockOperation,我没有意识到.您明确需要检查块中的 self.isCancelled).

(Interestingly this also applies for NSBlockOperation, which I didn't realise. You explicitly need to check self.isCancelled in the block).

我在 App Store 上使用了 CodeRunner 来尝试这个全部完成并稍微修改您的程序.转载如下.

I used CodeRunner on the App Store to try this all out and modified your program slightly. It's reproduced below.

#import <Foundation/Foundation.h>

int main(int argc, char *argv[]) {
    @autoreleasepool {
        NSOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"op1"); }];
        NSOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"op2"); }];
        NSOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"op3"); }];

        [op3 addDependency:op2];
        [op2 addDependency:op1];

        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        queue.maxConcurrentOperationCount = 1;

        [queue addOperations:@[op1, op2, op3] waitUntilFinished:YES];
    }
}

要使 NSBlockOperation 引用自身,您需要这样做,这有点恶心,但在 NSOperation 子类中看起来更好,因为您可以参考 自我.

For a NSBlockOperation to refer to itself you need to do this, which is a bit disgusting but looks better in a NSOperation subclass as you can refer to self.

__block NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"op1 cancelled=%d", op1.cancelled); }];

这篇关于NSOperationQueue:一系列具有依赖关系的 NSOperation&amp;#39;s VS (maxConcurrentOperationCount == 1)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆