グラフィックを最新の状態に保つのに問題がある場合、マルチスレッドを開始する前に...
displayまたはへのすべての呼び出しを削除しsetNeedsDisplay、それらを次のように置き換える必要がありますsetNeedsDisplayInRect:
drawRect:ビューの必要な部分のみを再描画するように、メソッドを最適化する必要があります。このメソッドでさらに凝ったrectものを取得し、メソッドからの引数を無視して、から描画される生のrectを取得できgetRectsBeingDrawn:count:ます。
動くオブジェクトを描く場合は、CoreAnimationを使用してください。
繰り返されるオブジェクトがたくさんある場合は、CGLayerRefsを使用します
で呼び出す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