iOS启动页动画加载(内存优化问题)

需求:在APP启动时加载一段动画

我们所知的实现方式

  1. 加载一段视频实现
  2. 使用GIF格式的动画(类似多张PNG用UIImageView做动画效果)
  3. .......
关于使用SDWebImage加载GIF格式动画的实现
  • 原理
    ** 使用UIImageView加载多张PNG,在一定时间内按帧数显示即可 *
    此处附上3张图表示使用动画前后和优化之后的内存占比(此处截图为模拟器Run):


    iOS启动页动画加载(内存优化问题)_第1张图片
    未加载动画.png
iOS启动页动画加载(内存优化问题)_第2张图片
加载动画之后.png
iOS启动页动画加载(内存优化问题)_第3张图片
优化动画加载之后.png

** 是不是发现1.46G被吓坏了。。诺诺的装个逼,此时貌似只有我的手机可以跑(iPhone 7 Plus) **

  • 优化过程
  1. 首先我们肯定是先发现这个问题,使用真机运行用Instruments中的Allocations(内存分配检测)效果如图:
iOS启动页动画加载(内存优化问题)_第4张图片
内存分配查看.png
iOS启动页动画加载(内存优化问题)_第5张图片
内存来源.png
  • 通过上面的图来分析,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,得到我们的猜测是正确的

解决方案

  1. 采用YY_WebImage框架:https://github.com/ibireme/YYWebImage
  2. 使用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"];
}
  1. 使用FLAnimatedImage:https://github.com/Flipboard/FLAnimatedImage

附上学习文章给大家(下文出自其他作者)

  1. 使用SDWebImage加载大量图片后造成内存泄露的解决办法:http://www.cnblogs.com/ziip/p/4664234.html
  2. SDWebImage加载.gif 内存狂飙问题:http://www.jianshu.com/p/6c71f0ca96f6
  3. SDWebImage 加载显示 GIF 与性能问题:http://www.cnblogs.com/silence-cnblogs/p/6682867.html
  4. Github的描述:https://github.com/rs/SDWebImage/issues/538
  5. 以上文章如需其他注明,请联系我,谢谢。

** 文章写得不是很好,不过希望大家能有所获,谢谢大家的支持!!! **

你可能感兴趣的:(iOS启动页动画加载(内存优化问题))