iphone - 可以在后台线程上调用dawRect:导致崩溃吗?

标签 iphone multithreading crash drawrect

我有一些繁重的UI绘制操作,因此我将其传递给了后台线程。我报告的崩溃中大约有100%发生在此操作中。当图形在主线程上运行时,就没有这种问题了,代码只是被取消了。

有在后台绘制的风险吗?

(我正在填充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];
}

关于iphone - 可以在后台线程上调用dawRect:导致崩溃吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9344697/

相关文章:

ios - 核心数据内存高效迁移

visual-studio-2008 - 在 Release模式下 Internet Explorer 8 崩溃后,我需要调试我的 BrowserHelperObject (BHO)(在 C++ 中使用 Visual Studio 2008)

crash - JpCapWriter使JVM崩溃

python - 如何监控python wsgi服务器,当它崩溃时重新启动它

iphone - 全屏 View 隐藏导航和标签栏 iphone

ios - 内容更改时 WKWebView 不调整大小

iphone - 构建时 Xcode 找不到我的 plist 文件

java - 使用线程循环更新 JFrame

C# - 线程中止和 System.NullReferenceException

multithreading - 如何将对堆栈变量的引用传递给线程?