1

我有大量对象(通常为 500 - 2000)呈现到屏幕上。不幸的是,目前渲染并不完全灵活。

每个对象都需要执行一些占用大部分时间的计算,最后将自己绘制到屏幕上,即目前我的drawRect:方法看起来基本上是这样的
:(为了可读性

- (void)drawRect:(NSRect)dirtyRect
{
   for (Thing *thing in [self getThings])
   {
        [thing prepareForDrawing];
        [thing draw];
   }
}

并发处理的明显候选者,对吧?

我想不出一个很好的方法来将准备工作与实际绘图操作分离,即并行执行预处理并以某种方式将绘图命令排队,直到所有处理完成,然后一次性渲染所有内容。

但是,考虑到GCD的优点,我想出了以下方案。
对我来说这听起来不错,但对 GCD 来说是新手,在公开发布四周后遇到奇怪的多线程问题之前,或者通常只是使用糟糕的 GCD 设计模式,我想我会征求反馈意见。

任何人都可以看到这种方法的问题 - 潜在问题或更好的解决方案?

- (void)drawRect:(NSRect)dirtyRect
{
   [[self getThings] enumerateObjectsWithOptions:NSEnumerationConcurrent
                                      usingBlock:^(id obj, NSUInteger idx, BOOL *stop)
   {
      // prepare concurrently
      Thing *thing = (Thing*)obj;
      [thing prepareForDrawing];

      // always draw in main thread
      dispatch_async(dispatch_get_main_queue(), ^{
         [thing draw];
      });
   }
}
4

1 回答 1

3

那是行不通的,因为调用[thing draw]-drawRect:在它完成之后发生。图形上下文将不再有效地绘制到该视图中。

为什么“东西”没有提前准备好?-drawRect:用于绘图,而不是计算。任何必要的昂贵计算都应该提前完成。

于 2013-03-30T15:22:53.057 回答