我正在尝试在后台线程中加载UIImages,然后在iPad上显示它们.但是,当我将imageViews的视图属性设置为图像时,会出现断断续续的情况.我很快发现iOS上的图像加载是懒惰的,并且在这个问题中找到了部分解决方案:
在UI线程上懒洋洋地加载CGImage/UIImage会导致口吃
这实际上会强制图像加载到线程中,但在显示图像时仍然存在断断续续的情况.
你可以在这里找到我的示例项目:http://www.jasamer.com/files/SwapTest.zip(编辑:修复版),检查SwapTestViewController.尝试拖动图片以查看口吃.
我创建的测试代码是断断续续的(forceLoad方法是我从上面发布的堆栈溢出问题中获取的方法):
NSArray* imagePaths = [NSArray arrayWithObjects:
[[NSBundle mainBundle] pathForResource: @"a.png" ofType: nil],
[[NSBundle mainBundle] pathForResource: @"b.png" ofType: nil], nil];
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock: ^(void) {
int imageIndex = 0;
while (true) {
UIImage* image = [[UIImage alloc] initWithContentsOfFile: [imagePaths objectAtIndex: imageIndex]];
imageIndex = (imageIndex+1)%2;
[image forceLoad];
//What's missing here?
[self performSelectorOnMainThread: @selector(setImage:) withObject: image waitUntilDone: YES];
[image release];
}
}];
Run Code Online (Sandbox Code Playgroud)
我知道可以避免口吃的原因有两个:
(1)Apple可以在照片应用中加载图像而不会出现断断续续的情况
(2)在上述代码的此修改版本中,placeholder1和placeholder2已显示一次后,此代码不会导致断断续续:
UIImage* placeholder1 = …
Run Code Online (Sandbox Code Playgroud) 我有一个后台线程加载图像并在主线程中显示它们.我注意到后台线程几乎无事可做,因为实际的图像解码似乎是在主线程中完成的:
到目前为止,我已经尝试过调用[UIImage imageNamed:]
,[UIImage imageWithData:]
并且CGImageCreateWithJPEGDataProvider
在后台线程中没有任何区别.有没有办法强制解码在后台线程上完成?
这里已经有类似的问题,但它没有帮助.正如我在那里写的,我尝试了以下技巧:
@implementation UIImage (Loading)
- (void) forceLoad
{
const CGImageRef cgImage = [self CGImage];
const int width = CGImageGetWidth(cgImage);
const int height = CGImageGetHeight(cgImage);
const CGColorSpaceRef colorspace = CGImageGetColorSpace(cgImage);
const CGContextRef context = CGBitmapContextCreate(
NULL, /* Where to store the data. NULL = don’t care */
width, height, /* width & height */
8, width * 4, /* bits per component, bytes per row */
colorspace, kCGImageAlphaNoneSkipFirst);
NSParameterAssert(context); …
Run Code Online (Sandbox Code Playgroud)