11

CGContextを保存および復元して、2回目の大量の描画計算を回避しようとすると、エラーが発生します<Error>: CGGStackRestore: gstack underflow

私は何が間違っているのですか?これを行う正しい方法は何ですか?

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    if (initialized) {
        CGContextRestoreGState(context);
        //scale context
        return;
    }

    initialized = YES;

    //heavy drawing computation and drawing

    CGContextSaveGState(context);
}
4

3 に答える 3

20

あなたは何を何をするのかを誤解しているかもしれないと思いCGContextSaveGState()ますCGContextRestoreGState()。現在のグラフィックス状態をスタックにプッシュしてポップすることで、現在の描画スペースを変換したり、線のスタイルを変更したりしてから、それらの値を設定する前の状態に戻すことができます。パスなどの描画要素は保存されません。

CGContextSaveGState()のドキュメントから:

各グラフィックス コンテキストは、グラフィックス状態のスタックを維持します。現在の描画環境のすべての側面がグラフィックス状態の要素であるとは限らないことに注意してください。たとえば、現在のパスはグラフィックス状態の一部とは見なされないため、 CGContextSaveGState()関数を呼び出しても保存されません。

グラフィックス ステート スタックは の開始時にリセットする必要がありますdrawRect:。これが、グラフィックス ステートをスタックからポップしようとするとエラーが発生する理由です。押していなかったので、飛び出すものはありませんでした。これはすべて、描画をグラフィックス状態としてスタックに保存し、後で復元できないことを意味します。

描画をキャッシュすることだけを心配している場合は、 (iPhone 上で)描画CALayerをバックアップする によって自動的に実行されます。UIViewビューを移動するだけの場合は、再描画されません。手動で描画するように指示した場合にのみ描画されます。図面の一部を更新する必要がある場合は、静的要素を独自のビューに分割するかCALayers、変更された部分のみを再描画することをお勧めします。

于 2009-09-18T22:24:37.013 に答える
7

最初に保存してから復元したくありませんか? 保存する前に復元する場合、復元するコンテキストがなく、アンダーフローが発生します。

これが私がそれを使用した方法です:

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextClipToRect(context, CGRectMake(stripe[i][8], stripe[i][9], stripe[i][10], stripe[i][11]));
CGContextDrawLinearGradient(context, gradient, CGPointMake(15, 5), CGPointMake(15, 25), 0);
CGContextRestoreGState(context);

また:

  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextSaveGState(context);
  CGContextAddRect(context, originalRect);
  CGContextClip(context);

  [self drawInRect:rect];

  CGContextRestoreGState(context);

たぶん、あなたは何か他のことをしようとしています。

于 2009-09-18T19:46:04.730 に答える