2010-07-04 80 views
0

我有一些iPhone SDK 4.0代码初始化NSOperationQueue,然后添加三个类(ClassA,ClassBClassC)一个接一个地运行。 ClassA,ClassBClassC都是NSOperation的子类。从NSOperation内取消NSOperationQueue

相关代码包含在下面。

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]; 

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

目前我很难弄清楚如何防止,例如,如果classA未成功完成,classB就不会运行。继续这个例子,我在想从classA以某种方式唤起[NSOperationQueue cancelAllOperations],但我不知道如何从classA(这是一个NSOperation子类)处理父NSOperationQueue。这只是我最初的想法,所以我会接受任何其他更好的建议来实现相同的结果!

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

任何建议将是最受欢迎的(和赞赏)。

+0

你是什么意思“未成功完成”。操作是否遇到错误或操作未完成? – falconcreek 2010-07-05 03:57:25

回答

3

你可以在CLASSA设置属性:

@property (readonly) BOOL completedSucessfully; 

,并在CLASSA的主要方法结束这个设置为YES。

然后,在classB的开始处检查它。

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

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

NB你可能会需要更多的错误检查,在上面即例如确保您有依赖性,检查它的正确类等

- (void)main { 
    for (id *temp in [self dependencies]) 
     if ([temp isKindOfClass:[ClassA class]]) 
      if (NO == [(ClassA *)temp finishedSucessfully]) 
       return; 
+0

谢谢院长。正是我需要:) – Skoota 2010-07-06 10:42:22

+0

这种设计有问题。 [dependencies objectAtIndex:0]可能为零。 – falconcreek 2010-07-06 15:05:52

+0

阅读第二个代码片段;)第一个被包含在内,以便快速阅读,第二个是我实际使用的。 – deanWombourne 2010-07-06 15:14:50

1

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

[selector:@selctor(StartB) waitUntilTaskComplete:YES]; 
1

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

  1. 从内部的NSOperation你可以调用[自我currentQueue]让“启动该操作或零如果队列无法确定操作队列中。”然后您可以在返回的队列上调用cancelAllOperations。在经验上我很难使用这种方法,因为如果你明确地在主队列上运行代码,在闭包/块中使用代码,或者调用第三方库,那么返回的队列可能根本就不是初始队列。在这种情况下,调用cancelAllOperations不会导致预期的行为 - 取而代之的是取消不同队列上的操作。

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

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

+0

'self.currentQueue'不是NSOperation的属性? – peterp 2015-10-27 17:07:23

+0

这是需要的,因为“初始”队列和“当前”队列之间存在差异。如果您有一个调用第三方库的操作,或者在闭包/块中运行代码,那么该代码实际上可能在最初的一个队列中执行。至少,这是我的经验(尤其是Facebook SDK)。 – 2015-10-27 18:14:16

相关问题