【问题标题】:Is this Core Graphics code thread safe?这个 Core Graphics 代码线程安全吗?
【发布时间】:2012-07-06 04:22:40
【问题描述】:

我知道只要我调用任何线程都是安全的

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 不是线程安全”的答案。我已经知道了。这是一个特殊情况(不要告诉我没有特殊情况)。)

(上面的代码运行良好,但我不确定这是否只是巧合。)

【问题讨论】:

  • 我认为您不会得到这个问题的明确答案,因为除了UIKit is is not thread safe(以及列出的例外情况),Apple 不会在文档中说明任何其他内容。你会得到来自其他人的意见和经验,但正如你所说,上面的代码工作正常,但谁能说它总是会,即使别人告诉你它会,会吗?
  • 线程规则是否也适用于修改或读取对象?
  • 如果我之前制作了视图的副本,那么我确定我是唯一可以访问这个新副本的方法吗?

标签: iphone objective-c ios core-graphics


【解决方案1】:

Core Graphics 和 Core Animation 是低级 API,通常是线程安全的。但是,关于访问的相同规则仍然适用:任何工作不得同时被多个线程访问,否则绘图将失败并且您的应用程序将崩溃。我会对 UIImage 保持警惕(但不害怕),因为 UIKit 对象不仅不是线程安全的,它们基本上是在后台线程中滴答作响的定时炸弹,并且会很高兴地无缘无故地从悬崖上直接跳入 Exception Land。但是,由于 UIImage 只是一个 CGImage 包装器,因此大多数绘图都是线程安全的。

【讨论】:

  • 那么在后台截屏有什么聪明的选择吗?在 bg 线程中使用 NSData,并在主线程中使用它来构建图像怎么样?
  • 后台截图?没有 IOSurface 是不可能的,感谢 Display Recorder,Apple 现在非常清楚地意识到了这一点,但是,如果这无关紧要,请参阅 here
  • 是的,这完全有可能,正如您自己所见,并且是安全的。上帝,我希望苹果能咬紧牙关,让 UIKit 线程安全,这样我们就不必一开始就进行这些讨论了……嗯,也许在 iOS 7 中,嗯?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 1970-01-01
  • 2020-02-15
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多