如何停止执行调度队列中的任务?
如果我有一个串行队列,我怎么能从主线程中告诉它立即停止执行并取消所有的任务?
这是一个很常见的问题,我曾经回答过:
暂停GCD查询问题
简单的答案是GCD没有取消API; 你必须自己实施你的取消代码。 在上面的答案中,我基本上显示了如何做到这一点。
从iOS 9 / OS X 10.11开始,如果没有自己实现非平凡的逻辑,就没有办法从调度队列中清空未完成的任务。
如果你需要取消一个调度队列,你最好使用NSOperationQueue
来提供这个和更多。 例如,以下是如何“取消”一个队列:
NSOperationQueue* queue = [NSOperationQueue new]; queue.maxConcurrentOperationCount = 1; // make it a serial queue ... [queue addOperationWithBlock:...]; // add operations to it ... // Cleanup logic. At this point _do not_ add more operations to the queue queue.suspended = YES; // halts execution of the queue [queue cancelAllOperations]; // notify all pending operations to terminate queue.suspended = NO; // let it go. queue=nil; // discard object
如果您使用的是Swift
则DispatchWorkItem
类允许单独取消作品单元。
工作项目允许您直接configuration各个工作单元的属性。 他们还允许您为了等待完成,收到通知完成和/或取消它们的目的,处理个别工作单位。 (可用于iOS 8.0或更高版本的MacOS 10.10以上)。
DispatchWorkItem封装可以执行的工作。 一个工作项目可以派发到一个DispatchQueue和一个DispatchGroup中。 DispatchWorkItem也可以设置为DispatchSource事件,注册或取消处理程序。
↳https ://developer.apple.com/reference/dispatch/dispatchworkitem
我不确定是否可以停止正在执行的当前块,但可以调用dispatch_suspend来阻止队列执行任何新的队列项目。 然后你可以调用dispatch_resume来重启执行(但是听起来不像你想做的那样)。
请参阅NSOperationQueue上的cancelAllOperations 。 确保您的操作正确处理取消消息仍然由您决定。
另一个解决scheme是扔掉旧队列并创build一个新队列。 这个对我有用。 这就像删除一个数组,你可以删除它的每个元素,或者你可以简单地创build一个新的replace旧的。