使用SDWebImage加载一个大的GIF导致iOS应用程序崩溃,内存错误

时间:2015-08-24 02:53:11

标签: ios crash gif sdwebimage

我正在UIImageView上使用SDWebImage框架在UIScrollView上从互联网上返回的网址获取全屏图像:

[imageView sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"placeholder"] options:SDWebImageCacheMemoryOnly completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
    if (!error) {
        //added as subview
    } else {
        //show error
    }
}];

当图片的格式为jpgpng时,它显示效果很好,甚至是一些正常大小的gif。但是当有一个很大的gif时,它会导致崩溃并且XCode会出现这样的错误:

Message from debugger: Terminated due to Memory Error

更新:每次导致崩溃的gif图片都是299px * 299px570KB。对于那些有兴趣看到gif的人,链接是:

http://ww4.sinaimg.cn/large/604e48d0jw1evcn03adjjg208b08bdv0.gif

每次点击预览缩略图时我都可以重新创建。 我怎么解决这个问题?用什么工具来观察根本原因?我做了一些研究,我想如果它是由于我使用选项SDWebImageCacheMemoryOnly引起的,而且我的应用程序的大部分内存占用了大gif,所以它崩溃了。感谢。

2 个答案:

答案 0 :(得分:1)

我注意到你的动画gif图像是一个很长的(就帧数而言)动画 - 3191帧。这些帧中的每一个都是300x300,总共几乎300 百万像素。我们必须一次将所有这些像素保存在内存中:没有其他方法可以快速显示帧。它似乎被编码为RGB,因此每个像素都是4个字节。如果我是对的,显示这个东西需要超过一亿GB的内存。这肯定是图形转换器的建议:

enter image description here

所以你是对的,我可以想象显示这个可能很麻烦。我的建议是:不要。

答案 1 :(得分:1)

SDWebImage有自己的GIF支持实现。问题是他们迭代思考所有帧并预先创建位图:

for (size_t i = 0; i < count; i++) {
    CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
    duration += [self sd_frameDurationAtIndex:i source:source];
    [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
    CGImageRelease(image);
}

另一方面,FLAnimatedImage按需创建位图并智能地缓存它们。

看看FLAnimatedImage。以及用于GIF播放的图像加载器,如Nuke(我的),PINRemoteImage,FLAnimatedImage_AFNetworking等。或者直接使用FLAnimatedImage。