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



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

为了简单起见,主要场景是:;

  • dispatch_queue_t实例(将处理给定UI更新块的队列)是一个串行调度队列(专用调度队列)

  • 操作(UI更新块)是用dispatch_after调度的,时间为t(不是为每个数据集更新进行更新,而是在t时间内收集更新请求并为其执行单个UI更新)

  • 如果我们的数据集更新了,请检查是否已经存在计划的事件。如果是,则从dispatch_queue_t实例取消调度。然后以t的时间延迟量重新调度同一块。

此外;

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

我的动机;

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

编辑:

正如@Sven建议的那样,NSOperationQueue的使用更适合该场景,因为它们支持取消每个NSOperation。我浏览了一下文件,发现;

正在取消操作添加到操作队列后,操作对象实际上由队列所有,不能删除。退出操作队列的唯一方法是取消操作。您可以通过调用单个操作对象的cancel方法来取消单个操作对象,也可以通过调用队列对象的cancelAllOperations方法来取消队列中的所有操作对象。

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

这也可以通过GCD轻松完成,无需在此处获取NSOperationQueue这一大锤子。

只需直接使用非重复调度定时器源,而不是dispatch_after(它只是围绕这样一个定时器源的一个方便包装,在定时器关闭之前,它实际上不会将块排入队列)。

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

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

相关内容

最新更新