ios - 创建 UIImage 线程安全吗?

标签 ios uiimage thread-safety

这样的调用是否被认为是线程安全的?它只是创建一个 UIImage,没有 UI 更新。我找不到关于此的任何文档。

UIImage * hiResImage = [[UIImage alloc] initWithContentsOfFile:path]; 

仅供引用,我稍后会像这样在主线程上更新 UI...

[imageViewForZoom performSelectorOnMainThread:@selector(setImage:) withObject:hiResImage waitUntilDone:NO];

我已经知道的:

  • 自 iOS4 以来,UIKit 的许多绘制方法都变成了线程安全的。从 here 读取.
  • 我不应该在后台线程上更新用户界面(例如,没有 [myImageView setImage:image];)

编辑:让我们看看另一个观点。 “非线程安全”是否意味着它有可能永远被阻塞?或者只是意味着不能保证开始/持续时间执行时间。如果是后一种情况,那么在加载图像时我们会有一些“不确定量”的延迟就没有问题了。 UI 更新在主线程上完成。因此,至少对于创建 UIImage 来说,它仍然被认为是非线程安全的。

我知道这与问题并没有真正的关系,但只是想指出它,因为我担心我原来的问题没有明确的答案:)

最佳答案

我下面的经验不是直接使用 UIImage initContentsFromFile:,而是使用 UIImage imageWithData,但您的问题是关于 UIImage 线程安全的。

我最近不得不调试使用 [UIImage imageWithData:] 的问题,该问题从 NSURLConnetionDelegate 函数 connectionDidFinishLoading 调用以下载图像几个后台线程。由于下载的图像用于更新 UI,因此我不得不使用下面的 [NSOperationQueue mainQueue] addOperationWithBlock ...:

- (void) connection:(URLConnection*)connection didReceiveData:(NSData *) data {
    [imgData appendData:data];
}

- (void) connectionDidFinishLoading:(NSURLConnection*)connection {
    [NSOperationQueue mainQueue] addOperationWithBlock:^{
        UIImage *img = [UIImage imageWithData:imgData];
        // more code here to update the UI
    }];
}
  • 在 iOS 7.x 模拟器上运行时,img 保存有效图像
  • 在 iOS 7.x 设备 (iPod Touch) 上运行时,img 始终为 nil

在调试 session 期间,我注意到当调试器一次一行地逐条执行每条语句时,问题(暂时)消失了。我的理论是,在调试器步进模式下运行不会让 UIImage 处理运行 imageWithData 的并发线程。因此,我相信 UIImage imageWithData(可能还有其他类似的函数)不是线程安全的。

使用 @synchronized block 似乎可以解决问题

- (void) connectionDidFinishLoading:(NSURLConnection*)connection {
    [NSOperationQueue mainQueue] addOperationWithBlock:^{
        @synchronized(imgData) {
            // Run the following in a synchronized block
            UIImage *img = [UIImage imageWithData:imgData];
        }
        // more code here ....
    }];
}

关于ios - 创建 UIImage 线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12766501/

相关文章:

iOS:UIImage 不可分配(FBSDKGraphRequest)

ios - 使用混合对图像着色/遮蔽前景

c++ - Qt 信号和槽线程安全

ios - "DateWithFormat"适用于终端但不适用于 iOS?

ios - 如何在 Swift 中将 CMSampleBuffer 转换为数据?

ios - Xcode Playground : "error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)"

ios - 适用于 iOS 的 Cordova 文件选择器?

ios - 快速将基于 RGB 值的 N 图像中的特定像素更改为不同的 RBG 颜色

java - 我的线程是否并行运行?

multithreading - 当多个线程尝试完全同时访问关键部分时,会发生什么情况?