0
我有一些沉重的UI繪圖操作,所以我把它傳遞給後臺線程。在這次行動中,大約有100%的事故報告發生。當繪圖在主線程上運行時,沒有出現這樣的問題,代碼只是解開了。可以調用dawRect:在後臺線程導致崩潰?
在後臺繪製任何風險?
(我填充UIScrollView的內容,可能是問題嗎?)
我有一些沉重的UI繪圖操作,所以我把它傳遞給後臺線程。在這次行動中,大約有100%的事故報告發生。當繪圖在主線程上運行時,沒有出現這樣的問題,代碼只是解開了。可以調用dawRect:在後臺線程導致崩潰?
在後臺繪製任何風險?
(我填充UIScrollView的內容,可能是問題嗎?)
首先,你不應該叫drawRect:
自己,UIKit的會替你。你應該打電話給setNeedsDisplay
。其次,UIKit不是線程安全的,因此在主線程以外的任何線程上調用任何UIKit繪圖操作都會導致應用程序崩潰,就像您遇到過的那樣。
但是,如果您創建上下文以自己繪製並僅使用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];
}
[什麼在iOS的新功能:iOS的4.0:UIKit框架的改進(HTTPS: //developer.apple.com/library/ios/releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html#//apple_ref/doc/uid/TP40009559-SW29):「在UIKit中繪製圖形上下文現在是線程安全的。「 – 2012-02-18 22:34:31
雖然跨線程傳遞UIKit提供的圖形上下文仍然不安全。 – 2012-02-18 22:35:40
感謝您的澄清,我錯過了。 – DarkDust 2012-02-18 22:47:01