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

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

问题描述

例如,我有3个对象:

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)

P.S.在我的应用程序中,我使用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. 如果颠倒op1op2的依赖顺序,则队列将运行op2op3op1op2op1op3.
  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子类中看起来更好,因为您可以引用self.

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的序列,具有依赖性VS(maxConcurrentOperationCount == 1)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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