【问题标题】:Adding NSOperation dependencies to operations already in an NSOperationQueue将 NSOperation 依赖项添加到已在 NSOperationQueue 中的操作
【发布时间】:2025-12-27 23:10:10
【问题描述】:

我想使用NSOperationQueue 实现一些后台网络请求。我有几个不同的请求将通过代码的不同部分添加到队列中,其中一个将比另一个更经常地运行。

我已经使用 GCD 实现了这个,所以我有代码块,因此我打算简单地使用 NSBlockOperation 方法 blockOperationWithBlock:^{...} 而不是创建 NSOperation 的子类。

这个问题是我想在请求之间创建依赖关系。如果队列已经有一个用于requestA 的NSBlockOperation,那么我想在为requestB 创建NSBlockOperation 时为其添加一个依赖项。同时创建操作时这很简单,但我找不到一种简单的方法来确定队列中已经存在哪些操作。

NSOperationQueue 有一个operations 属性,所以我可以自己检索操作列表,但是我如何确定哪个操作是哪个?我没有看到可以使用的名称/描述属性。

我能想到的选项是:

  1. 子类NSOperation 为每种请求类型创建自定义对象,然后对从operations 属性检索到的对象使用自省
  2. 子类NSBlockOperation并添加描述属性

我是否错过了其他一些明显的方法来做到这一点?

【问题讨论】:

  • 你不能让你的 NSBlockOperation 对象以一种你可以知道哪个是哪个的方式放置吗?

标签: objective-c ios multithreading nsoperation nsoperationqueue


【解决方案1】:

添加一个实例变量来保存最近的requestA 操作。在 requestA 块的末尾清除它。例如

_requestA = [NSBlockOperation blockOperationWithBlock:^{
    // Normal requestA code here.
    // ...

    // Assuming you create all requestA and requestB instances on the main thread...
    dispatch_async(dispatch_get_main_queue(), ^{ _requestA = nil; });
}];

然后当你创建一个requestB时,你可以给它最新的requestA作为依赖,如果还有一个要使用的话。

【讨论】:

  • 谢谢 Rob,这是一个很好的建议,我认为它会做我需要做的事情。我会试一试的。
【解决方案2】:

你可以使用优先级。

[NSBlockOperation setPriority:NSOperationQueuePriority]

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html

然后,当您枚举操作时,您可以检查优先级并将它们添加为依赖项或不添加。您甚至可能不需要检查它们,只需适当地设置操作的优先级即可。

【讨论】:

    【解决方案3】:

    我想说正确的方法是将 NSOperation 或 NSBlockOperation 子类化,并在这个子类中实现-(BOOL)isEqual:(id)object 方法,以便您可以比较在 NSOperationQueue 的操作属性中找到的操作。这样你应该可以使用内置的[operationA addDependency:operationB];

    【讨论】: