9

我在屏幕外绘制到一个CGContext创建的 using CGBitmapContextCreate,然后CGImage从中生成一个 withCGBitmapContextCreateImage并将其绘制到我的视图中drawRect(我还在上面绘制了一些其他的东西 - 这是一个隔离不同级别的可变性和复杂性的练习)。

当它全部在主线程上运行时,这一切都很好。然而,以这种方式拆分的动机之一是让屏幕外部分可以在后台线程上运行(我认为这应该没问题,因为它没有渲染到屏幕上下文)。

但是,当我这样做时,结果图像是空的!我检查了代码,并放置了明智的 NSLog 以验证一切都以正确的顺序发生。

我的下一步是将其归结为重现问题的最简单的代码(或找到我遗漏的一些愚蠢的东西并修复它)——如果有必要,我会在此处发布一些代码。但我首先想在这里检查一下我不会走错路。我在 googlesphere 的旅行中找不到任何可以说明问题的东西——但一位朋友确实提到他在尝试在后台线程中调整图像大小时遇到​​了类似的问题——这表明这里可能存在一些一般限制。

[编辑]

感谢您到目前为止的回复。如果没有别的,他们告诉我,至少我不是唯一一个对此没有答案的人——这是我想知道的一部分。在这一点上,我将把额外的工作放在尽可能简单的示例上,并且可能会返回一些代码或更多信息。同时保持任何想法:-)

需要提出的一点:有几个人在API 方面使用了术语线程安全。应该注意的是,在这种情况下有两种类型的线程安全:

  1. API 本身的线程性——即它是否可以在多个线程中使用(全局状态和其他重入问题,例如 C 的 strtok 是 API 可能不是线程安全的常见原因)。
  2. 单个操作的原子性 - 多个线程是否可以通过 API 与相同的对象和资源进行交互,而无需应用程序级锁定?

我怀疑到目前为止提到的是第一种类型,但如果你能澄清一下,我将不胜感激。

[edit2 - 解决了!]

好的,我得到了一切工作。执行摘要是问题出在我身上,而不是位图上下文本身。

在我的后台线程中,就在我进入位图上下文之前,我正在对其他一些对象进行一些准备。事实证明,间接地,对导致 setNeedsDisplay 在某些视图上调用的其他对象的调用!通过将执行此操作的部分分离到主线程,它现在一切正常。

因此,对于遇到这个问题的人想知道他们是否可以在后台线程上绘制位图上下文,答案是可以(这里和答案中已经提出了警告)。

谢谢大家

4

5 回答 5

3

只是一个猜测,但如果您尝试从另一个线程调用 setNeedsDisplay,则需要改为通过 performSelectorOnMainThread 调用它。

于 2009-04-01T08:30:00.980 回答
2

如果您在一个且只有一个线程中使用 CGContextRef,那么您所做的应该可以工作。我之前用 8 个内核处理图像的 8 个不同部分,然后将不同的结果 CGImageRef 合成在一起并在屏幕上绘制它们。

于 2009-04-01T01:46:20.700 回答
1

Apple 没有提及 iPhone 上的线程安全,但 Cocoa(相对于 UIKit)通常对于绘图来说是线程安全的。由于他们共享大量绘图代码,我认为在 iPhone 上绘图是线程安全的。

也就是说,您的经验表明存在问题。可能是您在渲染之前使用了图像吗?

于 2009-04-01T08:16:23.697 回答
0

并非所有 API 都是线程安全的。有些需要锁定或要求它们在主线程上运行。您可能需要搜索文档。我相信有一个页面总结了 SDK 的哪些部分是线程安全的,哪些不是。

于 2009-03-31T21:59:27.250 回答
0

万一有人正在/正在寻找如何做到这一点,我写了一篇博客文章,描述了如何做到这一点,并将整个事情包装在一个 NSOperation 子类中。

于 2010-12-16T09:30:11.533 回答