如何取消 NSOperation 的依赖?
How do I cancel an NSOperation's dependencies?
我在依赖图中有一些 NSOperation
s:
NSOperation *op1 = ...;
NSOperation *op2 = ...;
[op2 addDependency:op1];
我是这样的 运行 他们:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:op1];
[queue addOperation:op2];
现在我需要取消它们。如何确保依赖图中的所有 NSOperation
都被取消,并且没有其他 NSOperation
被取消?
我尝试过的:
在任一 NSOperation
上调用 cancel
不会取消另一个(据我所知):
[op1 cancel]; // doesn't cancel op2
// -- or --
[op2 cancel]; // doesn't cancel op1
取消队列也会取消不属于 op1
和 op2
的依赖图的操作(如果队列中有任何此类操作):
[queue cancelAllOperations];
所以我使用自定义方法解决了这个问题,该方法递归地查看 NSOperation
的依赖项并取消它们。但是,我对这个解决方案并不满意,因为我觉得我在与框架作斗争:
- (void)recursiveCancel:(NSOperation *)op
{
[op cancel];
for (NSOperation *dep in op.dependencies)
{
[self recursiveCancel:op];
}
}
不存在 NSOperation
自动取消其依赖关系的概念。这是因为多个 NSOperation
可能依赖于相同的其他 NSOperation
。严格存在依赖关系以延迟特定 NSOperation
的执行,直到其所有依赖项 NSOperation
完成。
你可以考虑写一个子类 NSOperation
:
@interface NSOperationOneToOne : NSOperation
- (void)addOneToOneDependency:(NSOperation *)operation;
- (void)removeOneToOneDependency:(NSOperation *)operation;
@end
@implementation NSOperationOneToOne {
NSMutableArray *oneToOneDependencies;
}
- (void)addOneToOneDependency:(NSOperation *)operation {
[oneToOneDependencies addObject:operation];
[self addDependency:operation];
}
- (void)removeOneToOneDependency:(NSOperation *)operation {
[oneToOneDependencies removeObject:operation];
[self removeDependency:operation];
}
- (void)cancel {
[super cancel];
[oneToOneDependencies makeObjectsPerformSelector:@selector(cancel)];
}
@end
注意:以上代码不保证没有错误。
在我看来,您正试图将操作分组到同一个队列中。为实现这一点,最好使用每组队列将它们分开。因此,为每个组在并发模式下创建一个 NSOperation 子类,包括一个队列,将每个 sub-operation 添加到队列中。覆盖取消并调用 [super cancel] 然后 [self.queue cancelAllOperations]。
这种方法的一个巨大优势是您可以通过再次添加到 sub-queue 来重试操作,而不会影响主队列的顺序。
我在依赖图中有一些 NSOperation
s:
NSOperation *op1 = ...;
NSOperation *op2 = ...;
[op2 addDependency:op1];
我是这样的 运行 他们:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:op1];
[queue addOperation:op2];
现在我需要取消它们。如何确保依赖图中的所有 NSOperation
都被取消,并且没有其他 NSOperation
被取消?
我尝试过的:
在任一 NSOperation
上调用 cancel
不会取消另一个(据我所知):
[op1 cancel]; // doesn't cancel op2
// -- or --
[op2 cancel]; // doesn't cancel op1
取消队列也会取消不属于 op1
和 op2
的依赖图的操作(如果队列中有任何此类操作):
[queue cancelAllOperations];
所以我使用自定义方法解决了这个问题,该方法递归地查看 NSOperation
的依赖项并取消它们。但是,我对这个解决方案并不满意,因为我觉得我在与框架作斗争:
- (void)recursiveCancel:(NSOperation *)op
{
[op cancel];
for (NSOperation *dep in op.dependencies)
{
[self recursiveCancel:op];
}
}
不存在 NSOperation
自动取消其依赖关系的概念。这是因为多个 NSOperation
可能依赖于相同的其他 NSOperation
。严格存在依赖关系以延迟特定 NSOperation
的执行,直到其所有依赖项 NSOperation
完成。
你可以考虑写一个子类 NSOperation
:
@interface NSOperationOneToOne : NSOperation
- (void)addOneToOneDependency:(NSOperation *)operation;
- (void)removeOneToOneDependency:(NSOperation *)operation;
@end
@implementation NSOperationOneToOne {
NSMutableArray *oneToOneDependencies;
}
- (void)addOneToOneDependency:(NSOperation *)operation {
[oneToOneDependencies addObject:operation];
[self addDependency:operation];
}
- (void)removeOneToOneDependency:(NSOperation *)operation {
[oneToOneDependencies removeObject:operation];
[self removeDependency:operation];
}
- (void)cancel {
[super cancel];
[oneToOneDependencies makeObjectsPerformSelector:@selector(cancel)];
}
@end
注意:以上代码不保证没有错误。
在我看来,您正试图将操作分组到同一个队列中。为实现这一点,最好使用每组队列将它们分开。因此,为每个组在并发模式下创建一个 NSOperation 子类,包括一个队列,将每个 sub-operation 添加到队列中。覆盖取消并调用 [super cancel] 然后 [self.queue cancelAllOperations]。
这种方法的一个巨大优势是您可以通过再次添加到 sub-queue 来重试操作,而不会影响主队列的顺序。