直到iOS 3.2,我使用这种代码在后台加载UIImageView图像,它运行良好.
代码:
- (void)decodeImageName:(NSString *)name
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *newImage = [UIImage imageNamed:name];
[myImageView setImage:newImage];
[pool release];
}
...
[self performSelectorInBackground:@selector(decodeImageName:) withObject:@"ID"]..。即使[UIImageView setImage:]不是线程安全的!
但是自从iOS 4之后,它就不再工作了.setImage调用后两秒钟,屏幕上就会出现图像。如果我做的是[myImageView performSelectorOnMainThread:@selector(setImage:) withObject:newImage waitUntilDone:YES]而不是[myImageView setImage:newImage],那么图像就会立即出现,但似乎会再次被动态解码(忽略之前应该已经解码了图像数据的[UIImage imageNamed:] ),导致我的主线程暂停.即使文档显示底层图像缓存在所有线程之间共享。
有什么想法吗?
发布于 2010-06-28 00:39:09
不要在后台做!这不安全。由于UIImageView也是NSObject,所以我认为在其上使用-[performSelectorOnMainThread:withObject:waitUntilDone:]可能会奏效,比如:
[myImageView performSelectorOnMainThread:@selector(setImage:) withObject:newImage waitUntilDone:NO];UIImage是新开发的线程安全系统。UIImageView仍然不是线程安全的。
发布于 2010-06-28 00:37:48
performSelectorInBackground:在后台线程中运行选择器。然而,setImage:是一个UI函数。UI函数只应在主线程上运行。我没有深入了解这个特定的问题,但这是关于这段代码的第一个直觉,而且可能是iOS4以某种不同的方式处理在后台线程中运行UI函数的(不受支持的)机制。
发布于 2010-06-28 03:55:26
如果您使用的是iOS 4.0,那么您应该考虑阅读块和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];
}https://stackoverflow.com/questions/3129434
复制相似问题