我有操作的依赖图,我使用多个队列来组织各种操作流。 例如。 peopleQueue,sitesQueue,sessionQueue
sessionQueue:loginOp,fetchUpdatedAccountOp peopleQueue:MostFrequentlyManagedClientsOp,remainingClientsOp sitesQueue:mostFrequentlyAccessedSitesOp,remainingSitesOp
依赖关系:
*all* -> loginOp
remainingClientsOp -> mostFrequentlyManagedClientsOp
remainingSitesOp -> mostFrequentlyAccessedSitesOp
当前设置有效:登录完成后,所有其他操作启动 mostFrequently *是一个子集提取,允许快速应用响应,后续操作在后台获取更多数据(有时在页面中)。
最近我想我会添加一个依赖于所有叶子操作的操作。 这个最新的操作将作为一个哨兵告诉我图形遍历何时完成(解雇它会导致NSNotification帖子或其他东西)。所以:
sentinelOp -> remainingClientsOp, remainingSitesOp, fetchUpdatedAccountOp
然而,我发现,即使所有依赖项都已完成,前哨操作也从未启动/触发。 当时的哨兵在会议队列中排队(没有特别的原因)。
在调试器中玩游戏之后,我发现如果哨兵只依赖于同一队列中的操作,我只能触发它。
我终于通过为该操作引入第4个队列来运行哨兵。 sentinel依赖于各自队列中的其他3个叶子操作,然后在它们全部完成时被调用。
我可以选择这种工作模式,但它确实困扰我。 mac和iOS的Apple docs表明队列间依赖性应该有效。
我需要进一步扩展图形,因此使用现有队列进行队列间依赖性会使操作无法执行。 显然,队列间依赖关系在某种程度上起作用,因为我首先将loginOp作为其他操作的根依赖,而不管它们的队列是什么。
将Sentinel操作放在现有的3个队列之一上,我做错了什么?
答案 0 :(得分:2)
我只使用了1个队列解决了这个问题。我仍然无法理解原始实现的错误,但我学到了一些不需要多个队列的东西。
首先,使用KVO观察队列待处理操作计数有点简单。这就是我能够取消哨兵的方式(见Reference)。
其次,我维护了几个队列来逻辑地分离出相关的操作。通过一个队列,我通过将操作生成方法组合成辅助方法,每个逻辑单元1,然后将帮助器返回的所有操作排入队列,实现了几乎相同的结果。
我不确定从3个队列到1是否存在性能影响据我所知,只要操作是并发的并且队列对当前执行没有限制,无论是否操作分布在多个队列中或全部在同一队列中。