2016-06-10 45 views
2

我正在更新关键部分内的窗口。因为在这个窗口中被绘制的数据被其他人(在另一个关键部分内)访问,所以我想要确保被绘制的窗口在我退出临界区时更新。如何确保NSWindow在代码块的末尾重新绘制

在Windows中,我可以使用InvalidateRect后跟UpdateWindow以确保存在强制绘制,并且执行消息而不是简单地将其推入队列,稍后标记为执行。

什么是在OSX中实现相同效果的相应方法?

从文档,似乎是这样的:

[myWindow display]其中myWindowNSWindow类型应该做的伎俩,但它不会立即绘制它。

有什么建议吗?

+0

所以你运行一个线程中的关键部分? –

回答

2

您可以通过在窗口中包含的视图上调用[self setNeedsDisplay]来强制执行它,然后在短时间内运行一个小运行循环以允许绘制消息传播到显示逻辑。

[viewToRefresh setNeedsDisplay]; 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
          beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 

这可能工作。它是一个相当奇怪的场景!因人而异。

+0

我已经尝试过,但我对运行循环的混乱有点怀疑。任何可能证实这样做的参考是安全的? – TheBlueNotebook

+0

我们一直在代码中使用这个非常不同的场景来允许通知通过。这不是一个想法的情况(通常我宁愿重构代码以去除依赖),但基本上Cocoa绘制循环不受您的控制。 –

1

首先,你从来没有画过一个窗口。你可以绘制视图。窗户只是视图的容器。

其次,视图应该知道自己,何时何地需要重新绘制。如果下方的数据发生变化,则报告该情况,但不报告请求。这是因为控制器不能禁止,视图的哪个区域受到影响。

不过,毕竟我认为窗口更新请求是从另一个线程发送的。

使用GCD它看起来像这样:

// Critical section ends here 
dispatch_async(dispatch_get_main_queue(), 
^{ 
    [affectedView setNeedsDisplay]; 
}); 

使用线程

// Critical section ends here 
[view performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];