NSOperation 依赖于不同队列上的另一个操作不会启动

Posted

技术标签:

【中文标题】NSOperation 依赖于不同队列上的另一个操作不会启动【英文标题】:NSOperation with dependency on another operation on a different queue does not start 【发布时间】:2013-12-13 22:13:44 【问题描述】:

我有操作的依赖图,我使用多个队列来组织各种操作流。 例如。人员队列、站点队列、会话队列

sessionQueue: loginOp, fetchUpdatedAccountOp peopleQueue: mostFrequentlyManagedClientsOp,remainingClientsOp sitesQueue: mostFrequentlyAccessedSitesOp, remainingSitesOp

依赖:

*all* -> loginOp
remainingClientsOp -> mostFrequentlyManagedClientsOp
remainingSitesOp -> mostFrequentlyAccessedSitesOp

当前设置有效:登录完成后,所有其他操作开始 mostFrequently* 是一个子集获取,允许应用快速响应,后续操作在后台获取更多数据(有时在页面中)。

最近我想我会添加一个依赖于所有叶子操作的操作。 这个最新的操作将充当一个哨兵,告诉我图遍历何时完成(触发它会导致 NSNotification 帖子或其他内容)。所以:

sentinelOp -> remainingClientsOp, remainingSitesOp, fetchUpdatedAccountOp

然而,我发现,即使它的所有依赖项都已完成,哨兵操作从未启动/触发。 哨兵,当时在 sessionQueue 上排队(没有特别的原因)。

在调试器中玩耍后,我发现只有在哨兵仅依赖于同一队列中的操作时才能触发它。

我终于通过为该操作引入第四个队列来运行哨兵。 sentinel 依赖于各自队列中的其他 3 个叶子操作,然后在它们全部完成时被调用。

我可以使用这种工作模式,但它真的让我很困扰。 mac 和 ios 的 Apple docs 表明队列间依赖应该起作用。

我需要进一步扩展图表,因此使用现有队列进行队列间依赖会阻止操作执行,这让我很困扰。 显然,队列间依赖在一定程度上起作用,因为我让 loginOp 成为其他操作的根依赖,而不管它们的队列如何。

将哨兵操作放在现有的 3 个队列之一上,我做错了什么?

【问题讨论】:

您的队列是并行的还是串行的?您是否尝试过其他现有队列?队列可能被阻止创建事实上的依赖关系。 三个队列都是并行的。不确定我是否收到您关于现有队列的问题 - 您的意思是将操作放在 [NSOperationQueue mainQueue] 之类的东西上吗?目前所有队列都是使用 [[NSOperationQueue alloc] init]; 创建的 【参考方案1】:

我只使用 1 个队列解决了这个问题。我仍然无法理解原始实现有什么问题,但我学到了一些东西,消除了对多个队列的需求。

首先,使用 KVO 观察队列待处理操作计数有点简单。这就是我能够摆脱哨兵的方式(参见Reference)。

其次,我维护了几个队列以在逻辑上分离出相关操作。使用一个队列,我通过将操作生成方法组合成辅助方法来实现几乎相同的结果,每个逻辑单元 1 个,然后将辅助方法返回的所有操作加入队列。

我不确定从 3 个队列变为 1 个队列是否会对性能产生影响。据我所知,只要操作是并发的并且队列对当前执行没有限制,是否应该无关紧要操作分布在多个队列中或全部在同一个队列中。

【讨论】:

以上是关于NSOperation 依赖于不同队列上的另一个操作不会启动的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot/Gradle/Querydsl项目有相同的依赖依赖于不同版本的另一个依赖

gcd和NSOperationQueue区别

GCD / NSOperation

NSOperation创建队列

如何将消息复制到 RabbitMQ 上的另一个队列?

iOS-多线程之NSOperation