1

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

@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 不允许这样做!

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

4

2 回答 2

4

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

正确的方法是将循环体移动到 NSOperation。您可以通过继承 NSOperation 或使用块创建一个来做到这一点。然后,将所有操作放入队列中。

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

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

进一步阅读:

于 2012-12-16T01:30:25.607 回答
1

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

于 2012-12-16T01:15:24.693 回答