1

我每 0.1 秒使用 NSTimer 从网格中绘制单元格。大小约为 96x64 => 6144 个单元格/图像。如果我正在绘制图像而不是(例如)绿色矩形,它会慢 4 倍!

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    UIGraphicsPushContext(context);
    CGContextSetRGBFillColor(context, 0, 0, 0, 1);
    CGContextFillRect(context, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height));
    int cellSize = self.bounds.size.width / WIDTH;
    double xOffset = 0;
    for (int i = 0; i < WIDTH;i++)
    {
        for (int j = 0; j < HEIGHT;j++)
        {                
                NSNumber *currentCell = [self.state.board objectAtIndex:(i*HEIGHT)+j];
                if (currentCell.intValue == 1)
                {
                   [image1 drawAtPoint:CGPointMake(xOffset + (cellSize * i),cellSize * j )];
                }
                else if (currentCell.intValue == 0){
                   [image2 drawAtPoint:CGPointMake(xOffset + (cellSize * i),cellSize * j )];
                }
        }
    }
    UIGraphicsPopContext();
}

如果我想在每个矩形中绘制 png 或 jpg,知道如何加快速度吗?图像已经缩放到适当的大小。

4

4 回答 4

3
  • a) 不要重绘视图边界之外的图像/矩形。

  • b)不要重绘dirtyRect之外的图像/矩形

  • c) 不要重绘自上次更新以来没有更改的图像/矩形。

  • d) 使用图层预渲染图像,因此您不需要在绘图时渲染它们。

于 2013-03-09T16:25:52.407 回答
2

这种情况正是 Instruments 的用途。用它。在这里提出建议的任何人都在猜测瓶颈是什么。

也就是说,我要猜测瓶颈是什么。您正在使用 CPU 绘制 6114 个图像(通过使用时间分析器确认这一点。找到您的 drawRect 方法,并检查花费最多时间的位置。如果是 drawInRect,那么这就是您的问题)

如果是这样,我们如何减少它的使用?一个简单的胜利就是只重绘我们需要绘制的图像。CALayers 让这一切变得简单。删除您的 drawRect 方法,为每个图像添加一个子层到您的视图层,并将图像设置为层的内容属性。当图像需要更改时,不要使视图无效,只需将相关层的内容属性切换到新图像即可。

CALayers 的另一个好处是它们在 GPU 上缓存图层内容,这意味着确实发生的重绘将需要更少的 CPU 时间,并且当它们发生时不会阻塞应用程序的其余部分。

如果这么多层的开销是不可接受的(同样,Instruments 是您的朋友),请查看 CAReplicatorLayer。它不如拥有许多 CALayer 灵活,但允许以最小的开销多次复制单个图像。

于 2013-03-09T23:50:20.413 回答
1

我试图从性能角度改进您的代码。但是,也请查看我对瓶颈的评论。

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    //UIGraphicsPushContext(context); //not needed UIView does it anyway

    //use [UIView backgroundColor] instead of this
    //CGContextSetRGBFillColor(context, 0, 0, 0, 1);
    //CGContextFillRect(context, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height));

    int cellSize = self.bounds.size.width / WIDTH;
    double xOffset = 0;

    CGRect cellFrame = CGRectMake(0, 0, cellSize, cellSize);
    NSUinteger cellIndex = 0;

    for (int i = 0; i < WIDTH; i++) {
        cellFrame.origin.x = xOffset;

        for (int j = 0; j < HEIGHT; j++, cellIndex++) {                
            cellFrame.origin.y = 0;

            if (CGRectIntersectsRect(rect, cellFrame) {
                NSNumber *currentCell = [self.state.board objectAtIndex:cellIndex];

                if (currentCell.intValue == 1) {
                    [image1 drawInRect:cellFrame];
                }
                else if (currentCell.intValue == 0) {
                    [image2 drawInRect:cellFrame];
                }
            }

            cellFrame.origin.y += cellSize;
        }

        cellFrame.origin.x += cellSize;
    }

    //UIGraphicsPopContext(context); //not needed UIView does it anyway
}
于 2013-03-09T17:12:20.343 回答
0

用于CGRectIntersects检查图像的矩形是否在dirtyRect 内,以检查是否需要绘制它。

于 2013-03-09T16:46:01.563 回答