需求:在APP启动时加载一段动画
我们所知的实现方式
- 加载一段视频实现
- 使用GIF格式的动画(类似多张PNG用UIImageView做动画效果)
- .......
关于使用SDWebImage加载GIF格式动画的实现
-
原理
** 使用UIImageView加载多张PNG,在一定时间内按帧数显示即可 *
此处附上3张图表示使用动画前后和优化之后的内存占比(此处截图为模拟器Run):
** 是不是发现1.46G被吓坏了。。诺诺的装个逼,此时貌似只有我的手机可以跑(iPhone 7 Plus) **
- 优化过程
- 首先我们肯定是先发现这个问题,使用真机运行用Instruments中的Allocations(内存分配检测)效果如图:
- 通过上面的图来分析,SDWebImage的源码(初始化方法)
+ (UIImage *)sd_animatedGIFNamed:(NSString *)name;
+ (UIImage *)sd_animatedGIFWithData:(NSData *)data;
- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size;
** 此处省略....看重点唯一注释处---数组没有得到释放 **
+ (UIImage *)sd_animatedGIFWithData:(NSData *)data {
if (!data) {
return nil;
}
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
size_t count = CGImageSourceGetCount(source);
UIImage *animatedImage;
if (count <= 1) {
animatedImage = [[UIImage alloc] initWithData:data];
}
else {
NSMutableArray *images = [NSMutableArray array];
NSTimeInterval duration = 0.0f;
for (size_t i = 0; i < count; i++) {
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
if (!image) {
continue;
}
duration += [self sd_frameDurationAtIndex:i source:source];
//数组没有得到释放
[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
CGImageRelease(image);
}
if (!duration) {
duration = (1.0f / 10.0f) * count;
}
animatedImage = [UIImage animatedImageWithImages:images duration:duration];
}
CFRelease(source);
return animatedImage;
}
大约计算375张的GIF图片*4M 约等于1.4G,得到我们的猜测是正确的
解决方案
- 采用YY_WebImage框架:https://github.com/ibireme/YYWebImage
- 使用SDWebImage:https://github.com/rs/SDWebImage;
在我们加载动画之前需要设置
{
SDImageCache *canche = [SDImageCache sharedImageCache];
SDImageCacheOldShouldDecompressImages = canche.shouldDecompressImages;
canche.shouldDecompressImages = NO;
SDWebImageDownloader *downloder = [SDWebImageDownloader sharedDownloader];
SDImagedownloderOldShouldDecompressImages = downloder.shouldDecompressImages;
downloder.shouldDecompressImages = NO;
}
在控制器dealloc中
{
SDImageCache *canche = [SDImageCache sharedImageCache];
canche.shouldDecompressImages = SDImageCacheOldShouldDecompressImages;
SDWebImageDownloader *downloder = [SDWebImageDownloader sharedDownloader];
downloder.shouldDecompressImages = SDImagedownloderOldShouldDecompressImages;
[[SDImageCache sharedImageCache] clearMemory];
[[SDImageCache sharedImageCache] clearDisk];
[[SDImageCache sharedImageCache] cleanDisk];
[[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"];
}
- 使用FLAnimatedImage:https://github.com/Flipboard/FLAnimatedImage
附上学习文章给大家(下文出自其他作者)
- 使用SDWebImage加载大量图片后造成内存泄露的解决办法:http://www.cnblogs.com/ziip/p/4664234.html
- SDWebImage加载.gif 内存狂飙问题:http://www.jianshu.com/p/6c71f0ca96f6
- SDWebImage 加载显示 GIF 与性能问题:http://www.cnblogs.com/silence-cnblogs/p/6682867.html
- Github的描述:https://github.com/rs/SDWebImage/issues/538
- 以上文章如需其他注明,请联系我,谢谢。
** 文章写得不是很好,不过希望大家能有所获,谢谢大家的支持!!! **