我有一些iPhone SDK 4.0代码初始化NSOperationQueue
,然后添加三个类(ClassA
,ClassB
和ClassC
)来一个接一个地运行。 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中的所有其他类运行。
任何建议都会受到欢迎(并赞赏)。
答案 0 :(得分:3)
您可以在classA中设置属性:
@property (readonly) BOOL completedSucessfully;
并在classA的主要方法结束时将其设置为YES。
然后,只需在classB的开头检查它。
- (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;
答案 1 :(得分:1)
我建议,如果速度不是问题,你可以同步工作。否则你可以使用:
[selector:@selctor(StartB) waitUntilTaskComplete:YES];
答案 2 :(得分:1)
在观看了有关高级NSOperation技术的WWDC 2015会议之后(强烈推荐),我开始在我自己的代码中深入使用它们。以下是实现此目的的一些建议
在NSOperation中,您可以调用[self currentQueue]来获取"启动操作的操作队列,如果无法确定队列,则调用nil。"然后,您可以在返回的队列上调用cancelAllOperations。根据经验,我很难使用这种方法,因为如果你在主队列上显式运行代码,在闭包/块中有代码,或者调用第三方库,那么返回的队列可能根本就不是初始队列。在这种情况下,调用cancelAllOperations将不会导致预期的行为 - 而是取消不同队列上的操作。
子类NSOperation包含初始NSOperationQueue和子类NSOperationQueue的属性,以便在将操作添加到队列时设置属性。然后在self.initialQueue上调用cancelAllOperations。这是我使用的方法,适用于上述所有场景。
您可以调用操作"取消"而不是取消队列级别的所有操作。方法并完成您的操作。如果您的操作已经编写为符合Apple的操作指南,那么它们在启动时都会检查isCancelled,如果为true则中止处理。这是一个微妙的区别:当您取消队列操作时,任何尚未启动的操作都将无法启动。当您将操作设置为isCancelled时,后续操作将启动,但(应该)之后很快完成。这允许后续操作可能执行某些清理,错误处理或用户通知的情况。