如何在GCD队列上停止/取消/暂停/恢复任务

时间:2015-04-07 13:22:31

标签: ios queue grand-central-dispatch

如何在GCD队列上停止/取消/暂停/恢复任务

如何停止后台队列操作?我想在我们的应用程序中停止一些屏幕。有些屏幕应该是自动恢复。那么,如何在iOS中传递队列?

我的意思是当用户浏览应用程序时,我们在dispatch_queue_t中运行后台线程。但它永远不会停止并在代码中恢复。那么如何暂停和恢复队列

2 个答案:

答案 0 :(得分:51)

要暂停一个调度队列,它只是Objective-C或Swift 2.3中的dispatch_suspend(queue)或Swift 3中的queue.suspend()。这不会影响当前正在运行的任何任务,而只是阻止新的任务来自从那个队列开始。此外,您显然只挂起您创建的队列(不是全局队列,而不是主队列)。

要恢复调度队列,它在Objective-C或Swift 2.3中是dispatch_resume(queue),在Swift 3中是queue.resume()。没有“自动恢复”的概念,所以你只需要手动在适当的时候恢复它。

要传递调度队列,只需传递在Objective-C或Swift 2.3中调用dispatch_queue_t时创建的dispatch_queue_create()对象,或者在Swift 3中传递DispatchQueue dispatch_block_cancel(block)。您使用DispatchQueue(label:)创建的对象。

在取消在调度队列中排队的任务方面,这是iOS 8的一项新功能,您可以使用Objective-C或Swift 2.3中的dispatch_block_t对象调用DispatchWorkItem,或{{ Swift 3中NSOperationQueue的3}}这将取消尚未启动的排队的块/项,但不会停止正在进行的排队。如果您希望能够中断已调度的块/项,则必须定期检查Objective-C和Swift 2.3中的item.cancel()或Swift 3中的dispatch_block_testcancel()

GCD块的取消非常复杂,我可能会向您推荐WWDC 2014视频item.isCancelled,它将向您介绍调度块对象的概念,排队,取消它们等等。旧的Objective-C和Swift 2.3 API,所有概念同样适用于较新的Swift 3 API。

如果你想取消任务,你也可以考虑在Objective-C或Swift 3中使用操作队列maxConcurrentOperationCount,在Swift 3中使用Power, Performance and Diagnostics: What's new in GCD and XPC,因为它的可取消操作已经存在虽然你可能会在网上找到很多例子。它还支持使用suspended约束并发度(而对于调度队列,您只能在串行和并发之间进行选择,并且控制并发性不仅仅需要您做出一点努力)。

如果使用操作队列,则通过更改队列的NSOperationQueue属性来暂停和恢复。要传递它,只需传递您实例化的NSTimer对象。


说完所有这些后,我建议你扩展你的问题,详细说明在后台运行什么类型的任务,并阐明你为什么要暂停它们。可能有比挂起后台队列更好的方法。


在您的评论中,您提到您在Swift 3中使用NSTimer,a.k.a。OperationQueue。如果您想停止计时器,请致电Timer停止计时。如果要再次启动它,请创建一个新的NSTimer

或者如果计时器确实在后台线程上运行,GCD计时器可以更加优雅地执行此操作,避免了需要在后台线程上创建runloop的愚蠢,您需要在后台线程上运行{{1}} 。使用GCD计时器,您可以暂停/恢复它,就像暂停/恢复队列一样,只需使用计时器对象而不是队列对象。

答案 1 :(得分:3)

使用GCD队列时无法暂停/取消。如果您需要该功能(在许多一般情况下即使您不需要),您应该使用更高级别的API - NSOperationQueue。它建立在GCD之上,但它使您能够同时控制执行的事物数量,暂停队列处理以及取消单个/所有操作。