使用 SDWebImage 加载大 gif 导致 iOS 应用崩溃并出现内存错误

Loading a big gif with SDWebImage caused iOS app crash with memory error

我正在使用 SDWebImage 框架从 UIImageView 中的 UIImageView 中从互联网返回的 url 获取全屏图像,如下所示:

[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 的人,link 是:

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

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

关于您的 gif 动画图像,我注意到它非常长(根据 帧数 )动画 - 3191 帧。这些帧中的每一帧都是 300x300,总共将近 300 百万 像素。而且我们必须一次将所有这些像素保存在内存中:没有其他方法可以快速显示帧。而且好像编码成RGB,所以每个像素都是4字节。如果我是对的,那么显示这个东西需要超过 1 GB 的内存。这当然是 Graphic Converter 所建议的:

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

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. And image loaders that use it for GIF playback like Nuke (mine), PINRemoteImage、FLAnimatedImage_AFNetworking等,或者直接用FLAnimatedImage