如何在GCD队列上停止/取消/暂停/恢复任务
如何停止后台队列操作?我想在我们的应用程序中停止一些屏幕。有些屏幕应该是自动恢复。那么,如何在iOS中传递队列?
我的意思是当用户浏览应用程序时,我们在dispatch_queue_t中运行后台线程。但它永远不会停止并在代码中恢复。那么如何暂停和恢复队列
答案 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之上,但它使您能够同时控制执行的事物数量,暂停队列处理以及取消单个/所有操作。