UIGraphicsBeginImageContextWithOptions和Multithreading

时间:2012-06-07 11:46:13

标签: ios multithreading uikit core-graphics

我对UIGraphicsBeginImageContextWithOptions和线程感到有点困惑,因为根据UIKit Function Reference UIGraphicsBeginImageContextWithOptions应该仅在主线程上调用。调用时,它会创建一个基于位图的上下文,可以使用CoreGraphics的函数或类似方法(例如drawInRect:用于UIImage-drawInRect:withFont:用于NSString和等等。对于CoreGraphics的绘图,一切都很清楚 - 您传递了一个CGContextRef参数,该参数被操作到每个函数,但UIKit绘图方法使用堆栈中的当前上下文。在What's New in iOS 4.0的发行说明中,它写了

  

在UIKit中绘制图形上下文现在是线程安全的。具体来说:
   - 用于访问和操作图形的例程
  上下文现在可以正确处理驻留在不同的上下文   线程。
- 字符串和图像绘制现在是线程安全的。
- 使用颜色和   现在可以安全地使用多个线程中的字体对象。

到目前为止一切顺利。有趣的是,我有一个项目,在那里我做了一些密集的绘图,并通过创建UIGraphicsBeginImageContextWithOptions的上下文来创建多个图像,但是当这些操作碰巧更耗时并且我只是在后台移动绘图线程和准备好时在屏幕上显示一些动画,一切正常 - 没有崩溃,没有泄漏。图像按照预期绘制,似乎UIGraphicsBeginImageContextWithOptions为后台线程创建了一个上下文,一切似乎都很好。
所以我的问题是:
  - 为什么有必要只在主线程上调用UIGraphicsBeginImageContextWithOptions,因为它似乎在后台工作正常?   - 如何使用UIImage的{​​{1}}方法,例如,在后台线程中,我没有当前上下文,我似乎无法创建一个因为我无法调用-drawInRect:那里?   - 什么是使用UIKit方法进行背景图像处理的正确方法(我知道我也可以使用UIGraphicsBeginImageContextWithOptions,但是它既不会将创建的上下文推送到上下文堆栈中,也不能自己做到这一点,以便使用CGBitmapContextCreate的{​​{1}}方法?

2 个答案:

答案 0 :(得分:24)

因此,经过几天的调查,如何操作UIKit上下文是线程安全的,但你似乎无法在main之外的线程中创建一个因为UIGraphicsBeginImageContextWithOptions“应该只在主线程上调用“,但仍然这样做完全正常,在阅读了关于这个主题的一些小帖子并与Apple开发人员论坛上的其他人讨论后,我可以清楚地说明,文档中有关于{{ 1}},UIGraphicsBeginImageContextWithOptionsUIGraphicsPushContext 错误,可以调用这些方法,并在其他线程中使用上下文而不会出现问题。因此UIGraphicsPopContextUIGraphicsBeginImageContextWithOptionsUIGraphicsPushContext 线程安全

答案 1 :(得分:0)

部分答案:使用UIGraphicsPushContext将您自己的CG上下文推送到“UIKit上下文”堆栈的顶部,所有内容(从该线程,我解释Apple的文档)将绘制到那个。不要忘记使用UIGraphicsPopContext从UIKit上下文堆栈中弹出它。

这适用于所有UIKit绘图操作;例如,绘制UIImage,就像你问的那样。推送上下文,绘制,然后弹出上下文。