0

iOS用の小さなペイントアプリを書いています。drawRect: メソッド内で計算を実行する UIView 広告をサブクラス化しています。たくさんのオブジェクト (実際にはポリライン) を使い始めるまでは問題なく動作していましたが、その後パフォーマンスが低下し始めました。

- (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 に答える