2013-02-21 104 views
9

我正在尝试重新排定将处理更新操作的排队块。 主要目标是用最少量的(UI更新请求)更新UI对象(在线用户表...)。 (服务器有时会降低大量更新,耶!)如何从GCD调度队列中删除排队的块?

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

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

  • 操作(UI更新块)被调度以dispatch_after与吨量时间(而不是更新每个数据集更新,在t时间内收集更新请求并为它们执行单个UI更新)

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

另外;

t是用户可能不会注意到的一小段时间间隔(如500毫秒) 任何其他方法都是可以接受的。

我背后的动机;

我应用相同的逻辑通过Android的处理程序(后& removeCallbacks组合与Runnable实例),我希望我可以在iOS上实现相同。

编辑:

作为@Sven建议NSOperationQueue的使用是更合适的为场景,因为它们支持消除每个的NSOperation。我通过文件浏览并找到;

取消操作 一旦添加到操作队列,操作对象被有效地由队列拥有和不能被移除。取消操作的唯一方法是取消操作。 您可以通过调用取消方法来取消单个操作对象,也可以通过调用队列对象的cancelAllOperations方法来取消队列中的所有操作对象。

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

回答

7

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

+0

我一直想看看NSOperationQueue的,因为他们是在AFNetworking框架大量使用。谢谢,如果可能的话,我会看看并标记为答案。 – 2013-02-21 16:04:33

13

这也可以很容易地用GCD完成,不需要在这里找到NSOperationQueue的大锤。

只需使用一个非重复的调度定时器源,而不是直接dispatch_after(这仅仅是围绕着这样一个定时器源一个便利的包装,它实际上并不排队该块到队列中,直到定时器熄灭)。

您可以重新挂起计时器源进行执行与dispatch_source_set_timer()

+1

'NSOperationQueue'是围绕GCD队列只是Objective-C的包装。你为什么认为它是“大锤”?它也为我提供了更简单的界面,所以我更喜欢它。 – Tricertops 2013-02-21 22:09:53

+11

这是不正确的。 NSOperationQueue不是GCD的包装,它是从GCD完全分开实现一个非常复杂的排队,依赖和优先跟踪系统。它在内部使用GCD进行一些同步(与自旋锁和互斥锁一起),但在执行客户端代码方面,与GCD的唯一连接是NSOperationQueue在末尾对全局并发队列执行dispatch_async()以在其执行操作准备好这样做。所有这些复杂性和灵活性都需要付出代价,NSOperationQueue比简单操作的GCD慢1000倍。 – das 2013-02-22 07:52:13

+5

的NSOperation围绕GCD更高级别的并发包装,使用志愿和GCD元到队列中管理的依赖关系。 QA1712,NSOperationQueue类的引用以及并发编程指南都提到了这一点。 NSOperations不应比GCD较慢为简单的操作(即addOperationWithBlock)次“1000”。如果是这样,你还在做其他事情。 – quellish 2013-02-24 06:52:36