【发布时间】:2012-12-18 13:18:02
【问题描述】:
在我正在处理的一个程序中,我正在执行大量数据处理,并且希望能够绘制一个自定义 NSView 以直观地表示该过程。
使用 GCD 从主线程处理数据处理(使用 dispatch_sync 作为需要保留的顺序):
for (int i=0; i<iterations; i++) {
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Add a data crunching task to the queue!
});
}
当处理开始时,我初始化了一个计时器,用于要求自定义显示定期重绘(一旦所有处理任务完成,这个计时器就失效了):
-(void)onTick:(NSTimer *)timer {
[_customView setNeedsDisplay:YES];
// Update some other UI object (labels etc.)
}
我按预期工作,但是我现在注意到的唯一问题是,如果我在同一窗口上单击并按住按钮,或者在进程进行时开始拖动滑块,重绘在我放开鼠标之前,自定义视图会被阻止!
有什么办法可以防止这种情况发生,最好不要将所有控件移到单独的窗口上!
【问题讨论】:
-
dispatch_sync本身并不“保持秩序”;使用它可以保持顺序,因为dispatch_sync一直等到分派的块返回(这就是上下文中“同步”的含义)。因此,您在调度下一个块之前等待每个块完成,这意味着您的循环与直接调用每个块的循环完全相同,只是您的循环涉及无效的后台队列。要在不阻塞主线程的情况下串行处理块,请创建并使用串行队列,或者使用 NSOperationQueue 并将每个操作设置为依赖于它之前的操作。 -
这很有意义。所以 dispatch_async 所以我不是挂在循环上等待返回,而是一个串行队列来维护后台线程的顺序。然后我的 GUI 会正确更新!非常感谢您花时间解释这一点!
标签: cocoa user-interface window nsview