【发布时间】:2023-04-08 01:17:01
【问题描述】:
我们遇到了一个关于 NSOperationQueue 的简单问题,下面是一个简单的操作逻辑:
self.queue = [[NSOperationQueue alloc] init];
NSOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"- Running operation A");
[NSThread sleepForTimeInterval:1.2];
NSLog(@"- Done operation A");
}];
NSOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"- Running operation B");
[NSThread sleepForTimeInterval:2];
NSLog(@"- Done operation B");
}];
[operationA setCompletionBlock:^{
NSLog(@"-- Completion Block A");
}];
[operationB setCompletionBlock:^{
NSLog(@"-- Completion Block B");
}];
[operationB addDependency:operationA];
[self.queue addOperations:@[operationA, operationB] waitUntilFinished:NO];
这是最终输出
2015-12-21 14:59:57.463 SampleProject[18046:310901] - Running operation A
2015-12-21 14:59:58.664 SampleProject[18046:310901] - Done operation A
2015-12-21 14:59:58.664 SampleProject[18046:310900] - Running operation B
2015-12-21 14:59:58.664 SampleProject[18046:310904] -- Completion Block A
2015-12-21 15:00:00.736 SampleProject[18046:310900] - Done operation B
2015-12-21 15:00:00.736 SampleProject[18046:310904] -- Completion Block B
我们可以看到,操作B在操作A的completionBlock之前执行。在我们的实际应用中,我们有很多操作A,只有一个操作B依赖于所有的操作A。但是我们遇到的问题是 operationB 在最后一个 operation A 的完成块被调用之前启动,这通常会向 operation B 提供信息。
我如何让操作B在所有操作A的完成块之后执行?
【问题讨论】:
-
可以选择切换到 GCD 吗?该 API 拥有您需要的所有工具。对于这种特殊情况,障碍块是您正在寻找的东西。有了这些,您可以并行运行许多 A 类任务,然后添加 B 类屏障任务,该任务在所有 A 完成之前无法启动,并且在 B 完成之前无法启动新任务。
-
你能给我一个简短的例子来说明它是如何工作的吗?我对 GCD 有点了解,但对这类任务还不够
-
老实说,我也不是专家,但前几天我读了 Ray Wenderlich 的tutorial,在第 1 部分“处理读者和作家问题”的中间,讨论了一些听起来很准确的东西喜欢你正在寻找的东西。
-
使用 GCD 可以做任何事情,就像编写汇编一样可以做任何事情。 NSOperationQueue 建立在 GCD 之上。只是实施起来要困难得多。尝试取消 dispatch_queues 上的依赖块。 NSOperations 免费!尝试使用 GCD API 更改操作优先级,而无需费力。屏障实际上会停止执行块的线程,而 NSOperation 使用 KVC/KVO 更轻松地执行此操作 - 通过不“准备好”执行 - 直到您依赖的操作“完成”。 dispatch_queues 继续运行而没有“障碍”。 NSOperations 摇滚!
标签: objective-c nsoperation nsoperationqueue