2012-02-18 9 views
0

重いUI描画操作があるので、バックグラウンドスレッドに渡しました。この操作中に報告されたクラッシュの約100%が発生しました。図面が主スレッド上で実行されたときに、そのコードが単なるコードになっていたような問題はありませんでした。バックグラウンドスレッドでdawRect:を呼び出すとクラッシュする可能性がありますか?

バックグラウンドで描画する危険性はありますか?すべての

(私はUIScrollViewの内容を移入しています、そこに問題がある可能性があります?)

答えて

7

まず、あなたがdrawRect:自分自身を呼び出すことになっていない、UIKitはあなたのためにそれを行います。あなたはsetNeedsDisplayに電話をする予定です。次に、UIKitはスレッドセーフではないため、メインスレッド以外のスレッドでUIKit描画操作を呼び出すと、経験したようにアプリケーションがクラッシュする可能性があります。

ただし、自分で描画するコンテキストを作成してCoreGraphics呼び出しのみを使用すると、CoreGraphicsはスレッドセーフです。ですから、CoreGraphicsを使ってバックグラウンドスレッドで時間を費やして描画することができます。CoreGraphicsでは、イメージコンテキストに描画し、イメージをインスタンス変数に格納します。次にメインスレッドでsetNeedsDisplayと呼び出し、レンダリングした画像をdrawRect:メソッドで表示します。擬似コード(コアグラフィックス版)でそう

- (void)redraw 
{ 
    [self performSelectorInBackground:@selector(redrawInBackground) withObject:nil]; 
} 

- (void)redrawInBackground 
{ 
    CGImageRef image; 
    CGContextRef context; 

    context = CGBitmapContextCreate(..., self.bounds.size.width, self.bounds.size.height, ...); 

    // Do the drawing here 

    image = CGBitmapContextCreateImage(context); 

    // This must be an atomic property. 
    self.renderedImage:[UIImage imageWithCGImage:image]]; 

    CGContextRelease(context); 
    CGRelease(image); 

    [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; 
} 

- (void)drawRect:(CGRect)rect 
{ 
    [self.renderedImage drawAtPoint:CGPointMake(0,0)]; 
} 

のUIKitバージョンは次のようになります。

- (void)redrawInBackground 
{ 
    UIGraphicsBeginImageContext(self.bounds.size); 

    // Do the drawing here. 

    self.renderedImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; 
} 
+0

[iOSの新機能:iOSの4.0:UIKitのフレームワークの拡張機能](HTTPS: //developer.apple.com/library/ios/releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html#//apple_ref/doc/uid/TP40009559-SW29): "UIKitのグラフィックスコンテキストへの描画はスレッドセーフです。 " –

+1

UIKitによって提供されるグラフィックスコンテキストをスレッド間で渡すことは、まだ安全ではありません。 –

+0

明確化のおかげで、私はそれを逃した。 – DarkDust

関連する問題