Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/119.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 创建UIImage是否线程安全?_Ios_Uiimage_Thread Safety - Fatal编程技术网

Ios 创建UIImage是否线程安全?

Ios 创建UIImage是否线程安全?,ios,uiimage,thread-safety,Ios,Uiimage,Thread Safety,这样的调用被认为是线程安全的吗?它只是创建一个UIImage,没有UI更新。我找不到关于这个的任何文档 UIImage * hiResImage = [[UIImage alloc] initWithContentsOfFile:path]; 仅供参考,我以后会像这样在主线程上更新UI [imageViewForZoom performSelectorOnMainThread:@selector(setImage:) withObject:hiResImage waitUntilDone:N

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

UIImage * hiResImage = [[UIImage alloc] initWithContentsOfFile:path]; 
仅供参考,我以后会像这样在主线程上更新UI

[imageViewForZoom performSelectorOnMainThread:@selector(setImage:) withObject:hiResImage waitUntilDone:NO];
我已经知道:

  • 自iOS4以来,UIKit的许多绘图方法变得线程安全。阅读
  • 我不应该在后台线程上更新ui(例如,no
    [myImageView setImage:image];
编辑:让我们看看另一个观点。“非线程安全”是否意味着它有可能永远被阻止?或者仅仅意味着无法保证开始/持续执行时间。如果是后一种情况,那么在加载图像时,如果我们会有一些“不确定的延迟量”,那么就没有问题了。UI更新在主线程上完成。所以,至少对于创建UIImage来说,它仍然被认为是线程安全的


我知道这与问题无关,但我只想指出这一点,因为我担心我原来的问题不会有明确的答案:)

是的。在后台加载图像是一种相当常见的做法,主要是当它是一个远程文件或正在加载许多图像时。是的,只更新主线程上的UI

编辑:


由于一些有启发性的评论,我将根据经验和我对加载映像时UIImage线程安全性不可行的替代方案的评估,将我的第一个答案“是”修改为“是”,我认为这是合理的假设。但是,每个人都有自己的观点,在任何情况下,可能他或她的代码失败风险太高,无法做出假设。

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

我最近不得不调试一个问题,即使用
[UIImage imageWithData::
NSURLConnetionDelegate
函数
connectiondifinishload
调用该函数,以使用多个后台线程下载图像。由于下载的图像用于更新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
在调试会话期间,我注意到当调试器一次一行地遍历每个语句时,问题(暂时)消失了。我的理论是,在调试器步骤模式下运行不会将
UIImage
放在处理运行
imageWithData
的并发线程上。因此,我认为
UIImage-imageWithData
(也许还有其他类似的函数)不是线程安全的

使用
@synchronized
块似乎可以解决这个问题

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

苹果表示,答案是肯定的,从任何线程创建UIImage都是安全的:

因为图像对象是不可变的,所以不能更改其属性 创建后的属性。大多数图像属性是自动设置的 在附带的图像文件或图像数据中使用元数据。这个 图像对象的不变性质也意味着它们对图像对象是安全的 从任何线程创建和使用


@Matt Q:创建UIImage线程安全吗?答:是的…--你有参考资料吗?这个重复问题的评论中有文档:@Matt你链接的文档与绘图
UIImage
s有关。但是,引用的文档没有说明创建。就我而言,jfortmann和CodaFi是链接QA的贡献者,我们应该注意。在图像的幕后有很多东西——在保证发布之前,对象之外的东西不一定是线程安全的。当然,人们会这样做,但这并不意味着它受到支持——操作系统更新甚至多线程工作负载的差异(设备或工作负载差异)都有可能破坏执行此操作的程序。这实际上是一个很好的问题,我认为适当的支持还有很长一段时间。您可能会认为我有妄想症,但我一直在使用其他方法在次线程上加载映像,因为(据我所知)这种保证从未存在过。@Eiko默认情况下,除非另有规定,否则应从主线程使用UIKit(和AppKit)类型。