2012-07-06 72 views
7

我知道它是安全的,只要我打电话此核心图形代码线程安全吗?

UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); 
UIGraphicsEndImageContext(); 
在同一个线程

在任何线程绘制。

通过这种方法拍摄一个视图的屏幕截图需要大约300毫秒,这并不坏,但我处于紧张的状况,所以我想在后台线程中做到这一点。

下面是我在做什么:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); 
     [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
     UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
    }); 

有问题的只是在这里的事情是view,它位于主线程。从后台线程调用view.layer上的renderInContext安全吗?或者一般来说,从另一个线程读取UIKit对象是否安全?

(请不要给我默认的“UIKit不是线程安全的”答案。我已经知道了。这里是一个特殊情况(并且不要告诉我没有特殊情况)。)

(上面的代码工作正常,但我不知道,如果这只是一个巧合。)

+0

我不认为你会得到这个问题的明确答案,因为在文档Apple中除了'UIKit是不是线程安全的'(以及列出的例外)之外的任何地方。你会得到的是来自其他人的意见和经验,但正如你所说的,上面的代码工作正常,但是谁说它总是会的,即使别人告诉你它会这样做,是吗? – Rog 2012-07-06 04:29:18

+0

线程规则是否也适用于修改或读取对象? – Snowman 2012-07-06 04:31:01

+0

如果我之前制作了一个视图副本,那么我确信我是这种方法是唯一一个可以访问这个新副本的方法吗? – Snowman 2012-07-06 04:32:22

回答

7

核芯显卡和核心动画是低级别的API,通常是线程安全的。但是,关于访问的相同规则仍然适用:任何工作不得同时由多个线程访问,否则绘图将失败并且您的应用程序将崩溃。我会对UIImage保持警惕(但并不害怕),因为UIKit对象不仅不是线程安全的,而且它们基本上都是在后台线程中滴答时间炸弹,并且会很乐意直接跳入悬崖峭壁进入Exception Land,无缘无故。但是,因为UIImage只是一个CGImage包装器,所以大多数绘图都是线程安全的。

+0

那么在背景中拍摄截图有没有一个聪明的选择?如何在bg线程中使用NSData,并使用它在主线程上构建图像? – Snowman 2012-07-06 04:36:49

+0

在后台截图?如果没有IOSurface,Apple可以非常清楚地意识到由于Display Recorder而非常清楚,但是,如果没有关系,请参阅[这里](http://stackoverflow.com/questions/11090184/how-does-the- /),使用 - 私-AP IOS-APP-显示记录器记录的屏幕,而无需-。 – CodaFi 2012-07-06 04:37:52

+0

不是在背景背景 - 我的意思是后台线程.. – Snowman 2012-07-06 04:43:44