在后台线程中加载UIImage

Max*_*Max 4 multithreading objective-c uiimage ios ios8

是否可以在后台线程中加载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];
        });

    });
Run Code Online (Sandbox Code Playgroud)

mat*_*att 14

你正在做的是结构合理,但我不知道是否imageNamed:是线程安全的 - 我没有理由相信它是.除非文档另有说明,否则您应该始终认为事情不是线程安全的.在这种情况下,文档明确指出不是:

您不能假设此方法是线程安全的.

在我看来,你应该问自己是否需要这样做.imageNamed:包括一个缓存机制,可以减轻你担心的任何问题.无论如何,过早优化会浪费你的时间和智力.这里真的有问题吗?用仪器找出; 不要使用直觉或本能.

如果问题是您的图像太大而且格式选择不当 - 例如,您使用的是非常大的JPEG - 那么最好集中精力纠正.

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

  • 我所看到的是` - [UIImage imageNamed:]`_used_是线程安全的...直到iOS 8.从那以后我看到很多崩溃是在后台线程上调用它引起的,我们一直在做的事情多年没有麻烦. (5认同)
  • 一年后续的附录:Apple更新了其文档,明确指出`[UIImage imageNamed:]`在iOS 9及更高版本中确实是线程安全的.这真是太棒了.https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/#//apple_ref/occ/clm/UIImage/imageNamed: (2认同)