0

我有一些 iPhone SDK 4.0 代码初始化 anNSOperationQueue然后添加三个类(ClassAClassBClassC)以一个接一个地运行。ClassA, ClassB, 和ClassC都是 的子类NSOperation

相关代码如下。

ClassA *classA = [[ClassA alloc] init];
ClassB *classB = [[ClassB alloc] init];
ClassC *classC = [[ClassC alloc] init];

[classB addDependency:classA];
[classC addDependency:classB];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[queue addOperation:classA];
[queue addOperation:classB];
[queue addOperation:classC];

[classA release];
[classB release];
[classC release];
[queue release];

依赖的原因是因为只有在成功完成其操作classB时才应该运行。classA同样,classC仅应在成功完成时运行classB

目前,我很难弄清楚如何防止,例如,如果没有成功完成,则无法classB运行。classA继续这个例子,我想以某种方式[NSOperationQueue cancelAllOperations]从内部唤起,classA但我不知道如何NSOperationQueue从内部classA(这是一个NSOperation子类)获得对父级的处理。这只是我最初的想法,所以我愿意接受任何其他更好的建议来达到同样的结果!

每个类中都有条件代码来确定它们是否已正确完成 - 目前它们只是 NSLogging “成功”或“失败”到控制台以进行调试。在一个完美的世界中,我希望能够NSLog(@"Fail")用一些代码替换每个类中的语句,这将阻止 NSOperationQueue 中的所有其他类运行。

任何建议都将受到欢迎(和赞赏)。

4

3 回答 3

3

您可以在 classA 中设置一个属性:

@property (readonly) BOOL completedSucessfully;

并在 classA 的 main 方法的末尾将其设置为 YES。

然后,只需在 B 类开始时检查它。

- (void)main {
    if (NO == [[dependencies objectAtIndex:0] completedSucessfully])
        return;

现在,如果 classA 报告失败,classB 将停止。

注意,您可能需要在上面的示例中进行更多错误检查,即确保您有依赖关系,检查它是否是正确的类等。

- (void)main {
    for (id *temp in [self dependencies])
        if ([temp isKindOfClass:[ClassA class]])
            if (NO == [(ClassA *)temp finishedSucessfully])
                return;
于 2010-07-04T10:15:43.617 回答
1

我建议,如果速度不是问题,您可以同步工作。否则你可以使用:

[selector:@selctor(StartB) waitUntilTaskComplete:YES];
于 2011-03-20T18:31:50.590 回答
1

在查看了 WWDC 2015 关于高级 NSOperation 技术(强烈推荐)的会议之后,我开始在我自己的代码中深入使用它们。以下是实现这一目标的一些建议

  1. 在 NSOperation 中,您可以调用 [self currentQueue] 来获取“启动操作的操作队列,如果无法确定队列,则为 nil”。然后,您可以在返回的队列上调用 cancelAllOperations。根据经验,我在使用这种方法时遇到了困难,因为如果您在主队列上显式运行代码,在闭包/块中包含代码,或者调用第三方库,那么返回的队列可能根本不是初始队列。在这种情况下,调用 cancelAllOperations 不会导致预期的行为 - 相反,您正在取消不同队列上的操作。

  2. 子类 NSOperation 包含初始 NSOperationQueue 的属性,子类 NSOperationQueue 用于在将操作添加到队列时设置属性。然后在 self.initialQueue 上调用 cancelAllOperations。这是我正在使用的方法,适用于上述所有场景。

  3. 您可以调用操作“取消”方法并完成您的操作,而不是取消队列级别的所有操作。如果您的操作已编写为符合 Apple 的操作指南,则它们都会在启动时检查 isCancelled,如果为真则中止处理。这是一个微妙的区别:当您取消队列操作时,任何尚未启动的操作将根本不会启动。当您将操作设置为 isCancelled 时,后续操作将开始,但(应该)在此之后不久完成。这允许以后的操作可能执行一些清理、错误处理或用户通知的情况。

于 2015-10-08T16:04:43.293 回答