我在窗口B的位置之后实现了窗口A的跟踪机制。窗口B发送其位置和窗口B的事件通过调用setWindowProperties
对这些事件作出反应:
void setWindowProperties(bool topMost, bool visible,
CGWindowID parentWindow, CGWindowID aboveWindow,
NSRect windowFrame, NSRect viewFrame, bool isAbove)
{
dispatch_async(dispatch_get_main_queue(), ^{
setWindowPropertiesImpl(topMost, visible, parentWindow, aboveWindow, windowFrame, viewFrame, isAbove);
});
}
但是,由于窗口B发送了太多事件,我得到了一条"蛇追踪"影响。我想通过仅对最后一个位置事件做出反应来克服它,这意味着取消之前的所有调用:
dispatch_async(dispatch_get_main_queue(), ^{
setWindowPropertiesImpl(topMost, visible, parentWindow, aboveWindow, windowFrame, viewFrame, isAbove);
});
结果,在队列中只留下最后一个位置事件 - 唯一重要的事件。
我的问题:有没有办法取消之前dispatch_async
的所有电话?
答案 0 :(得分:2)
是的,调度任务现在可以取消,但是当事件的进入速度超过主队列可以处理它们时,使用dispatch source有时很有用。特别是DISPATCH_SOURCE_TYPE_DATA_ADD
数据源。
// create source (and save this reference somewhere so it doesn't get released on you)
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
// specify what you want the event handler to do
dispatch_source_set_event_handler(source, ^{
// whatever you want to do
});
// start the dispatch source
dispatch_resume(source);
然后,当你想触发这个时,而不是dispatch_async
,你会:
dispatch_source_merge_data(source, 1);
显然,这意味着事件处理程序必须从其他窗口提取数据而不是推送它,但希望这说明了基本的想法。
有关详细信息,请参阅WWDC 2012视频Asynchronous Design Patterns with Blocks, GCD, and XPC。具体来说,请参见设计模式8,"异步更新状态"在视频的后半部分。
答案 1 :(得分:0)
您无法取消在调度队列中排队的操作。
GCD队列一旦安排就无法取消阻止。这个建筑非常“火上浇油”。#/ p>。
您可以使用也可以异步执行的NSOperationQueue代替GCD,然后您可以取消。