Multithreading iOS4&;背景[UIImage setImage:]

Multithreading iOS4&;背景[UIImage setImage:],multithreading,ios4,uiimage,Multithreading,Ios4,Uiimage,在iOS 3.2之前,我使用这种代码在后台加载UIImageView图像,效果很好 代码: 。。。即使[UIImageView setImage:不是线程安全的 但是自从iOS 4以后,它就不再工作了。。。调用setImage两秒钟后,屏幕上会显示图像。如果我使用object:newImage waitUntilDone:YES执行[myImageView performSelectorOnMainThread:@selector(setImage:)而不是[myImageView setIma

在iOS 3.2之前,我使用这种代码在后台加载
UIImageView
图像,效果很好

代码:

。。。即使
[UIImageView setImage:
不是线程安全的

但是自从iOS 4以后,它就不再工作了。。。调用
setImage
两秒钟后,屏幕上会显示图像。如果我使用object:newImage waitUntilDone:YES执行
[myImageView performSelectorOnMainThread:@selector(setImage:)而不是
[myImageView setImage:newImage]
,图像会立即出现,但似乎会在运行中重新解码(忽略以前的
[UIImage-imageNamed:]
它应该已经解码了图像数据),导致我的主线程暂停。。。即使文档中说底层映像缓存在所有线程之间共享


有什么想法吗?

执行选择器背景:
在后台线程中运行选择器。但是setImage:是一个UI函数。UI函数只能在主线程上运行。我没有洞察到具体的问题,但这是对这段代码的第一个直觉,可能是iOS4在后台线程中运行UI函数的机制(不受支持)有所不同。

不要在后台这样做!它不是线程安全的。由于
UIImageView
也是一个
NSObject
,我认为对其使用
-[performselectornmainthread:withObject:waitUntilDone:
可能会起作用,如:

[myImageView performSelectorOnMainThread:@selector(setImage:) withObject:newImage waitUntilDone:NO];

它是
UIImage
,这是新开发的线程安全工具<代码> UIIVIEVIEW 仍然不是线程安全的。

< P>如果您使用的是IOS 4,您应该真正考虑在块和GCD上阅读。使用这些技术,您可以简单地将您的方法替换为:

- (void)decodeImageName:(NSString *)name
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    UIImage *newImage = [UIImage imageNamed:name];

    dispatch_async(dispatch_get_main_queue(), ^{
        [myImageView setImage:newImage];
    }

    [pool release];
}
让我们引用:

@属性(非原子,只读)CGImageRef CGImage

讨论

如果由于内存限制而清除了图像数据,则调用此方法将强制将该数据加载回内存。重新加载图像数据可能会导致性能损失

所以您可以直接调用
image.CGImage
。我不认为CGImages是懒惰的

如果这不起作用,可以使用以下命令强制渲染

// Possibly only safe in the main thread...
UIGraphicsBeginImageContext((CGSize){1,1});
[image drawInRect:(CGRect){1,1}];
UIGraphicsEndImageContext();

一些人警告线程安全。文档说,
UIGraphics{Push,Pop,GetCurrent}Context()
只是主线程,但没有提到任何关于
UIGraphicsBeginImageContext()的内容。如果您担心,请使用
CGBitmapContextCreate
CGContextDrawImage

这没有多大帮助。dispatch_async仍然会将主线程暂停的时间比它应该暂停的时间长,就好像uiimage被重新解码一样。我如何确定UIImage是在[UIImage ImageName:name]之后解码的?我建议支持OS 3.1.3至少几个月,支持3.2直到iPad 4.0+发布后几个月。嗨,Evadne,你从哪里读到UIImage是线程安全的?到处都找不到。你好,谢谢你问这个问题。我想知道为什么我的应用程序现在无法使用它。
// Possibly only safe in the main thread...
UIGraphicsBeginImageContext((CGSize){1,1});
[image drawInRect:(CGRect){1,1}];
UIGraphicsEndImageContext();