0

我正在为 iOS 编写一个小型绘画应用程序。我将 UIView 广告子类化,在其 drawRect: 方法中执行计算。一切都很好,直到我开始有很多对象(实际上是折线),然后性能开始下降。

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGContextRef imageContext = UIGraphicsGetCurrentContext();

    int i, j;
    for(i = 0; i < [_strokes count]; i++) {
        NSMutableArray *stroke = [_strokes objectAtIndex:i];
        if([stroke count] < 2) {
            continue;
        }
        CGContextSetStrokeColorWithColor(imageContext, [[_penColours objectAtIndex:i] CGColor]);
        for(j = 0; j < [stroke count]-1; j++) {
            CGPoint line[] = {
                [[stroke objectAtIndex:j] CGPointValue],
                [[stroke objectAtIndex:j+1] CGPointValue]
            };

            CGContextSetLineWidth(imageContext, _brushSize);
            CGContextSetLineCap(imageContext, kCGLineCapRound);
            CGContextSetLineJoin(imageContext, kCGLineJoinRound);

            CGContextAddLines(imageContext, line, 2);
            CGContextStrokePath(imageContext);
        }
    }

    CGContextFlush(imageContext);
}

其中 _strokes 是点数组的数组。我的第一个想法是将图像制作为 ivar,将其绘制在上下文上,将额外的笔画绘制到上下文(j = 0用更改j = [stroke count] - 2),然后将上下文抓取到图像并将其存储回 ivar。没用。

然后我尝试了许多其他不值得一提的道路,直到我在 SO(Quartz2D 性能 - 如何改进)上发现了另一个问题。不幸的是,它没有像我预期的那样工作,因为我必须保留图像,导致内存警告 1、2、崩溃。

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    UIGraphicsBeginImageContext(CGSizeMake(1024, 768));
    CGContextRef imageContext = UIGraphicsGetCurrentContext();

    if(_image != nil) {
        CGContextDrawImage(imageContext, CGRectMake(0, 0, 1024, 768), [_image CGImage]);
    }

    int i, j;
    for(i = 0; i < [_strokes count]; i++) {
        NSMutableArray *stroke = [_strokes objectAtIndex:i];
        if([stroke count] < 2) {
            continue;
        }
        CGContextSetStrokeColorWithColor(imageContext, [[_penColours objectAtIndex:i] CGColor]);
        for(j = [stroke count]-2; j < [stroke count]-1; j++) {
            CGPoint line[] = {
                [[stroke objectAtIndex:j] CGPointValue],
                [[stroke objectAtIndex:j+1] CGPointValue]
            };

            CGContextSetLineWidth(imageContext, _brushSize);
            CGContextSetLineCap(imageContext, kCGLineCapRound);
            CGContextSetLineJoin(imageContext, kCGLineJoinRound);

            CGContextAddLines(imageContext, line, 2);
            CGContextStrokePath(imageContext);
        }
    }

    _image = UIGraphicsGetImageFromCurrentImageContext();
    [_image retain];
    UIGraphicsEndImageContext();

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, CGRectMake(0, 0, 1024, 768), [_image CGImage]);
}
4

1 回答 1

1

看起来至少部分问题是您保留了 _image 但您从未释放它。每次为 _image 分配新值时,都会泄漏前一个图像,这会很快填满内存。

除此之外,您可能应该使用CGLayer进行离屏绘图,而不是位图。您可以随时绘制到图层中,然后只需在您的 -drawRect: 方法中将其复制到屏幕上。

于 2011-06-01T10:33:00.670 回答