【问题标题】:Load UIImage in background Thread在后台线程中加载 UIImage
【发布时间】:2014-10-25 12:22:15
【问题描述】:

是否可以在后台线程中加载 UIImage 而不会导致线程问题? 如果不是最好的方法是什么?我正在使用 iOS 8。这就是我现在的方式:

    dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_async(backgroundQueue, ^{
        UIImage *image = [UIImage imageNamed: fileName];

        // only update UI on the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            [self setImage: image];
        });

    });

【问题讨论】:

  • 你当前的例子有什么问题?
  • 我曾经在后台加载图像时遇到 CG ImageIO 错误,所以我想知道为什么会这样。这里的人说你不应该在后台加载 UIImages 并且可以解决它。
  • 也许imageWithContextOfURl 应该对您有所帮助,而不是url,而是将您的nsbundle 的路径作为url。 stackoverflow.com/questions/4962561/…

标签: ios objective-c multithreading uiimage ios8


【解决方案1】:

你所做的在结构上是合理的,但我不知道imageNamed: 是否是线程安全的——我没有理由相信它是。除非文档另有说明,否则您应该始终假设事情是线程安全的。在这种情况下,documentation specifically says 它是不是

你不能假设这个方法是线程安全的。

在我看来,您应该问自己是否需要这样做。 imageNamed: 包含一个缓存机制,可以让您摆脱担心的任何事情。无论如何,过早的优化都是在浪费你的时间和脑力。这里真的有问题吗?使用仪器找出答案;不要使用直觉或直觉。

如果问题是您的图像太大并且格式选择不正确(例如,您使用的是非常大的 JPEG),那么最好集中精力更正那个。 p>

编辑 iOS 9 文档现在说:“在 iOS 9 及更高版本中,此方法是线程安全的。”这表明我的回答是正确的,并且问题现在已经解决了。

【讨论】:

  • 感谢您的快速响应。我意识到 imageNamed 有缓存,但第一次加载需要时间。我正在为背景加载大量图像,并且我想在它们完成加载时呈现它们,因此他们的用户根本看不到任何延迟。
  • 我所看到的是 -[UIImage imageNamed:] 使用 是线程安全的......直到 iOS 8。从那以后我看到很多由于调用它而导致的崩溃一个后台线程,我们多年来一直在做的事情没有遇到任何麻烦。
  • @DarkDust 非常有用的信息,感谢添加。有人可能会狡辩说imageNamed: 可能不是 实际上是线程安全的——除非我们被明确告知它是线程安全的,否则没有什么是线程安全的——但你的经验是,你以前能够使用它在后台(即使您可能不应该这样做)而现在您不能这样做,这当然很有趣。
  • @DarkDust Docs 特别提到imageNamed:“你不能假设这个方法是线程安全的。”所以如果你总是这样做,你总是做错了。
  • 一年后的附录:Apple 已更新其文档以明确声明 [UIImage imageNamed:] 在 iOS 9 及更高版本中确实是线程安全的。这真是一个了不起的消息。 developer.apple.com/library/ios/documentation/UIKit/Reference/…:
猜你喜欢
  • 2012-02-16
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
相关资源
最近更新 更多