如何从GCD调度队列中删除排队的块?

时间:2013-02-21 15:02:30

标签: ios grand-central-dispatch

我正在尝试重新安排将处理更新操作的排队块。 主要目标是以最少量(UI更新请求)更新UI对象(在线用户表...)。 (服务器有时会下大量的更新,是的!)

为简单起见,主要情况是;

  • dispatch_queue_t实例(将处理给定UI更新块的队列)是串行调度队列(私有调度队列)

  • 使用dispatch_after调度操作(UI更新块),使用t时间量(而不是更新每个数据集更新,在t时间内收集更新请求并为它们执行单个UI更新)< / p>

  • 如果我们的数据集已更新,请检查是否已存在预定事件。如果是,则从dispatch_queue_t实例中取消计划。然后用t量的时间延迟重新安排相同的块。

也;

t是用户可能不会注意到的少量时间间隔(如500毫秒)。 欢迎任何替代方法。

我背后的动机;

我通过Android的Handler应用相同的逻辑(post&amp; removeCallbacks与Runnable实例的组合),我希望我能在iOS上实现相同的目标。

修改

由于@Sven建议使用NSOperationQueue更适合场景,因为它们支持取消每个NSOperation。我浏览了一些文件并找到了;

  

取消操作   一旦添加到操作队列,操作对象就被队列有效拥有,无法删除。使操作出列的唯一方法是取消它。 您可以通过调用取消方法取消单个操作对象,也可以通过调用队列对象的cancelAllOperations方法取消队列中的所有操作对象。

     

只有在您确定不再需要操作时,才应取消操作。发出取消命令会将操作对象置于“已取消”状态,从而阻止其运行。由于取消的操作仍被视为“已完成”,因此依赖于它的对象会收到相应的KVO通知以清除该依赖关系。因此,更常见的是取消所有排队操作以响应某些重要事件,例如应用程序退出或用户特别请求取消,而不是有选择地取消操作。

2 个答案:

答案 0 :(得分:14)

这也可以通过GCD轻松完成,无需在这里找到NSOperationQueue的大锤。

直接使用非重复调度计时器源而不是dispatch_after(这只是一个围绕这样一个计时器源的便利包装器,它实际上并不会将块排入队列,直到计时器关闭)

您可以使用dispatch_source_set_timer()重新安排待处理的计时器源执行。

答案 1 :(得分:6)

您无法删除或以其他方式更改在调度队列中排队的操作。请尝试使用支持取消的更高级别NSOperationQueue