有没有办法让NSView重绘更频繁?

时间:2012-12-15 23:58:23

标签: cocoa user-interface drawing nsview

我目前有一些代码可以做这样的事情(大规模简化,但足以说明这一点):

@property (weak) IBOutlet CustomViewClass *customView;

...

for (int i=0; i<iterations; i++) {

    // Crunch some data (Up to ~200,000 operations)...

    // Update view to represent where we are in the process:
    [_customView setNeedsDisplay:YES];

}

每当我为给定的迭代次数运行代码时,一旦所有迭代完成,自定义视图drawRect:方法只被调用一次。

我希望在每次迭代后强制更新视图,并等到视图重新绘制后再进行下一次迭代 - 但我在文档中的任何地方都找不到如何使其工作正如我所愿!

我觉得如果我可以直接调用drawRect:那会解决我的问题,但我知道NSView不允许这样做!

有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:4)

缺乏视图更新甚至不是您当前方法的最大问题。最大的问题是你的应用程序挂起直到它完成。用户无法取消(如果您甚至提供了取消按钮),请告知应用程序隐藏,在工作进行时在应用程序中执行任何其他操作,或退出应用程序。

正确的方法是将循环体移动到NSOperation。您可以通过继承NSOperation或使用块创建一个来完成此操作。然后,将所有操作都放入queue

如果您在循环中执行的操作safely可以并行运行,那么您应该创建一个队列并使用该队列。如果您需要一次执行一个操作,请使用依赖项将每个操作链接到之前的操作。如果绝对必须在主线程上发生,你可以使用主队列,但是你应该在你可以安全逃脱的主线程上做最少的数量。

随着工作的进行,在主线程/主队列上运行一些代码,告诉您的视图为setNeedsDisplay:。由于操作不在主队列上(假设您没有将它们放在那里),或者至少是分解,这可能会在工作正在进行时发生。

进一步阅读:

答案 1 :(得分:1)

不确定这是否是您想要的,但请尝试使用CVDisplayLink。 http://developer.apple.com/library/mac/#qa/qa1385/_index.html