2013-03-24 117 views
2

我有一些代码使用一个UIImageView,这里显示的动画GIF图像:https://github.com/amleszk/GifBlocking避免图像解压缩阻塞主线程

它非常适用的情况下99%,虽与某种类型的问题GIF图像,可以在这里找到一个例子:http://i.imgur.com/mbImw.gif

这个gif接收101张图像,然后在显示包含动画图像的UIImageView时阻止主线程。如果它有压缩,它可以解压gif,但是如何阻止这个阻塞主线程?

是被调用在主线程的方法是 DGifDecompressInput DGifDecompressLine copyImageBlockSetGIF

问题是GIF当视图被添加到层级减压发生 - 这应该在主线程中完成

谢谢

+1

*“一些类似于...的代码”非常模糊。没有看到确切的代码就很难提供帮助。 – 2013-03-24 13:23:53

+0

添加了一个git repo在这里重现:https://github.com/amleszk/GifBlocking – amleszk 2013-03-24 16:32:44

回答

5

grasGendarme的代码是有用的,但要注意的UIImage是懒惰和图像,直到它真的不会解码需要。关键是你必须使用CGContextDrawImage在后台线程上强制解压缩。因此,使用UIImage+JTImageDecode.h在后台创建一个未压缩的图像版本,然后将其设置回主线程。

+0

工作正常(缺点是图像渲染两次?),git repo已经更新了一个例子。 – amleszk 2013-03-24 22:46:30

+0

渲染意味着从格式化数据生成图像。在这里,图像被渲染(解压缩)一次,然后保存在UIImage对象上,并稍后转储到视频内存中。无论您是分两步还是一步完成,图像只会呈现一次。 – Jano 2013-03-24 23:01:22

+0

我试过这个,我所谓的动画UIimage不再是动画,它只是显示第一帧 - 我忽略的其他东西? – 2013-03-27 21:45:55

2

这将是很高兴看到实际的代码。没有这个,我们的帮助是有限的。

也许你可以把一条线:

[self performSelectorInBackground:@selector(yourBlockingMethod:) withObject:yourObject]; 

或修改您的库解压缩在后台线程的GIF,然后在主线程上使用setNeedsDisplay

2

你可以让一切发生在使用大中央调度和串行队列一个单独的线程:

// create the queue that will process your data: 
dispatch_queue_t dataProcessQueue = dispatch_queue_create("data process queue", NULL); // the name is there for debugging purposes 
    //dispatch to the newly created queue, and do not wait for it to complete 
    dispatch_async(dataProcessQueue, ^{ 
     // load and decode gif 
     // ... 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      // put gif in place (UI work always happen on the main queue) 
      // ... 
    }); 
});