グラフィックを最新の状態に保つのに問題がある場合、マルチスレッドを開始する前に...
display
またはへのすべての呼び出しを削除しsetNeedsDisplay
、それらを次のように置き換える必要がありますsetNeedsDisplayInRect:
drawRect:
ビューの必要な部分のみを再描画するように、メソッドを最適化する必要があります。このメソッドでさらに凝ったrect
ものを取得し、メソッドからの引数を無視して、から描画される生のrectを取得できgetRectsBeingDrawn:count:
ます。
動くオブジェクトを描く場合は、CoreAnimationを使用してください。
繰り返されるオブジェクトがたくさんある場合は、CGLayerRef
sを使用します
で呼び出すsetNeedsDisplay
とdispatch_async()
、ビューが別のスレッドに描画されることはありません。すべての描画はで行われdrawRect:
、drawRect:
常にメインスレッド/キューによって呼び出されます。
UIGraphicsGetCurrentContext()
スレッドセーフではありません。ただし、非同期ブロックにビットマップコンテキストを作成し、ストロークしてそのコンテキストに入力し、このコンテキストをCGImageRefとして取得して、で実行されているCGContextRef(画面と通信しているもの)にコンプすることができます。メインスレッド。次のようになります。
@implementation BGDrawingClass : UIVew {
CGImageRef bgImage;
}
-(void)prepBGImage {
CGRect rect = TheRectISpendALotOfTimeIn();
dispatch_async(_myBGQueue,^{
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(nil, rect.size.width, rect.size.height, 8, rect.size.width * (CGColorSpaceGetNumberOfComponents(space) + 1), space, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(space);
/* do expensive drawing in this context */
bgImage = CGBitmapContextCreateImage(ctx);
dispatch_async(dispatch_get_main_queue(),^{
[self setNeedsDisplayInRect:rect];
});
});
}
-(void)drawRect:(NSRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
/* do drawing behind this ... */
if (CGRectIntersectsRect(rect, TheRectISpendALotOfTimeIn()) {
CGContextDrawImage(ctx, TheRectISpendALotOfTimeIn(), bgImage);
}
/* do drawing in front of this */
}
@end