0

以下は、私の自己定義ビューの drawRect です。チェス盤を描画します。盤には 19*19 の線があり、上下に文字、左右に 1 ~ 19、また 9 つのドットがあります。

- (void)drawRect:(CGRect)rect
{
    // Get the drawing context
    CGContextRef context = UIGraphicsGetCurrentContext ();

    CGContextSaveGState(context);

    // Draw the board background
    UIImage *bk = [UIImage imageNamed:@"board_bg_011.png"];

    CGColorRef shadowColor = CreateDeviceRGBColor(0.5, 0.5, 0.5, 1);
    CGContextSetShadowWithColor(context, CGSizeMake(2, 2), 10, shadowColor);
    [bk drawInRect:CGRectMake(TEXT_AREA_OFFSET, TEXT_AREA_OFFSET, self.bounds.size.width - TEXT_AREA_OFFSET * 2, self.bounds.size.height - TEXT_AREA_OFFSET * 2)];

    CGColorRelease(shadowColor);
    CGContextRestoreGState(context);

    // Draw board edage square
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:tableRect];
    path.lineWidth = 2.0;
    [path stroke];

    // Draw board lines
    UIBezierPath *line = [UIBezierPath bezierPath];
    line.lineWidth = 1.0;
    for (int i = 1; i <= 17; i ++) {
        float x = tableRect.origin.x + i * qiziSize;
        [line moveToPoint:CGPointMake(x, tableRect.origin.y)];
        [line addLineToPoint:CGPointMake(x, tableRect.origin.y + tableRect.size.height)];
        [line stroke];

        float y = tableRect.origin.y + i * qiziSize;
        [line moveToPoint:CGPointMake(tableRect.origin.x, y)];
        [line addLineToPoint:CGPointMake(tableRect.origin.x + tableRect.size.width, y)];
        [line stroke];
    }

    // Draw 9 dots
    CGContextSaveGState(context);

    CGRect dotRect = CGRectMake(0, 0, 6, 6);
    CGContextTranslateCTM(context, tableRect.origin.x + qiziSize * 3 - 3, tableRect.origin.y + qiziSize * 3 - 3);
    UIBezierPath *dot = [UIBezierPath bezierPathWithOvalInRect:dotRect];
    [dot fill];

    CGContextTranslateCTM(context, qiziSize * 6, 0);
    [dot fill];

    CGContextTranslateCTM(context, qiziSize * 6, 0);
    [dot fill];

    CGContextTranslateCTM(context, - qiziSize * 12, qiziSize * 6);
    [dot fill];

    CGContextTranslateCTM(context, qiziSize * 6, 0);
    [dot fill];

    CGContextTranslateCTM(context, qiziSize * 6, 0);
    [dot fill];

    CGContextTranslateCTM(context, - qiziSize * 12, qiziSize * 6);
    [dot fill];

    CGContextTranslateCTM(context, qiziSize * 6, 0);
    [dot fill];

    CGContextTranslateCTM(context, qiziSize * 6, 0);
    [dot fill];

    CGContextRestoreGState(context);

    CGContextSaveGState(context);

    UIFont *font = [UIFont fontWithName:@"Helvetica" size:12];
    int fontHeight = [@"1" sizeWithFont:font].height;
    UIColor *textColor = [UIColor grayColor];
    [textColor setFill];
    [textColor setStroke];

    for (int i = 1; i <= 19; i ++) {
        // Top text
        NSString *str = [NSString stringWithFormat:@"%c", ((i < 9)?i:(i+1)) + 'A' - 1];
        CGRect textRect = CGRectMake(tableRect.origin.x + qiziSize * (i - 1) - qiziSize / 2, 0, qiziSize, TEXT_AREA_OFFSET);
        [str drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter];

        // Bottom text
        textRect.origin.y = self.bounds.size.height - TEXT_AREA_OFFSET + 2;
        [str drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter];

        // Left text
        str = [NSString stringWithFormat:@"%i", i];
        textRect = CGRectMake(0, tableRect.origin.y + qiziSize * (i - 1) - fontHeight / 2, TEXT_AREA_OFFSET - 2, fontHeight);
        [str drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentRight];

        // Right text
        textRect.origin.x = self.bounds.size.width - TEXT_AREA_OFFSET + 2;
        [str drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentLeft];
    }

    CGContextRestoreGState(context);
}

iPad3 で実行すると、このメソッドは 1 秒以上かかります。それを最適化する方法について何か提案はありますか?

前もって感謝します。

4

1 に答える 1

2

これは、回転性能の低下に関する以前の質問に続くものだと思います。

画像とフォントの作成と描画 (およびスケーリング) にはコストがかかります。計測器で時間プロファイラーを使用すると、コードの最もコストのかかる領域が強調表示されますが、それらは最も可能性の高い候補です。

ビューを UIImageView および UILabel インスタンスに分解することを検討する必要があります。これらのインスタンスはバッキング ストアをキャッシュし、再描画する必要はなく、再配置するだけです。ただし、コードをプロファイリングしてパフォーマンスのボトルネックを見つけるまでは、何もしないでください。

于 2012-10-07T15:51:48.300 に答える