美文网首页
关于列表加载多张高清图片导致的内存过大的问题

关于列表加载多张高清图片导致的内存过大的问题

作者: 七码_Z | 来源:发表于2018-03-30 11:31 被阅读0次

转载:https://blog.csdn.net/benyoulai5/article/details/50462586。自己抄录仅作学习。
之前做的一个项目中,一个tableview的列表加载了很多图片,并且后台返回的图片都是大图,并不是压缩图,导致一下子内存过大,就崩溃了

网上给的方法说可以每次加载图片清空memchche,但是效果并不好。

[[SDImageCache sharedImageCache] setValue: nil forKey:@"memCache"];

也有说把使用下面这个方法的地方全部注释掉

+(UIImage *)decodedImageWithImage:(UIImage *)image

但是效果并不明显,同时加载多张高分辨率图片还是会立即崩溃

我们使用SDWebImage肯定会做的三件事,一是判断本地是否有这张图,二是有的时候直接从本地读取图片,三是本地没有图片就去网络上下载。大概像这样

NSString * logoString = [_currentDic stringValueForKey:@"team_img"];
if (logoString.length>0){
       [SDImageCache shareImageCache] queryDiskCacheForKey:logoString done:^(UIImage *image,SDImageCacheType cacheType) {

              if (image) {
                      [_teamImage setImage:image];
               }else{
                      [_teamImage sd_setImageWithURL:kNSUrl(logoString) placeholderImage: IMGNAMED(@"defaultAvatar2")] options: SDWebImageRefreshCached completed:^(UIImage *image,NSError *error,SDIMageCacheType cacheType, NSURL *imageURL) {
                                  if(image){
                                          [[SDImageCache sharedImageCache] storeImage:image forKey:logoString toDisk: YES];
                                  }
                        }
                }
      }];
}

在内部都是使用到下面这个方法

-(UIImage *)diskImageForKey:(NSString *)key {
              NSData * data = [self diskImageDataBySearchAllPathForKey:key];
              if (data){
                        UIImage * image = [UIImage sd_imageWithData: data];
                        image = [self scaledImageForKey: key image:image];
                        image = [UIImage decodeImageWithImage: image];
              }else{
                         return nil
              }
}

重点是这里

UIImage *image = [UIIMage sd_imageWithData:data];

图片取出来的时候就已经巨大无比,占用了很大的内存,导致内存来不及释放就崩溃了。接下来进入

sd_imageWithData方法
发现这里面对图片的处理是直接按照原大小进行的,如果几千是分辨率这里导致占用了大量内存! 更改前的sd_setImageWithData.png

所以我们需要在这里对图片做一次等比压缩
我们在UIImage+MultiFormat这个类里面添加如下压缩方法。

+(UIImage*)compressImageWith:(UIImage *)image{
    
    float imageWidth = image.size.width;
    float imageHeight = image.size.height;
    float width = 640;
    float height = image.size.height / (image.size.width/width);
    
    float widthScale = imageWidth / width;
    float heightScale = imageHeight / height;

    // 创建一个bitmap的context  
    // 并把它设置成为当前正在使用的context 
    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    if (widthScale > heightScale) {
        [image drawInRect:CGRectMake(0, 0, imageWidth /heightScale , height)];
    }
    else {
        [image drawInRect:CGRectMake(0, 0, width , imageHeight /widthScale)];
    }
    
    // 从当前context中创建一个改变大小后的图片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    // 使当前的context出堆栈
    UIGraphicsEndImageContext();
    
    return newImage;
}
再在上面箭头代码后面对图片进行压缩! 更改后的sd_setImageWithData.png

到了这里还需进行最后一步,就是在SDWebImageDownloadOperation的connectionDidFinishLoading方法里面的:

UIImage *image = [UIImage sd_imageWithData:self.imageData];

添加后面代码

NSData *data = UIImageJPEGRepresentation(image, 1);
self.imageData = [NSMutableData dataWithData:data];
就是这样子 下载图片之后压缩.png

再配合[[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"];图片加载出来之后使用这行代码

[[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"];
在cell里面加载之后.png

大功告成!亲测内存变化不大,自动释放也来得及。

关闭打赏,仅作学习!

相关文章

网友评论

      本文标题:关于列表加载多张高清图片导致的内存过大的问题

      本文链接:https://www.haomeiwen.com/subject/glibcftx.html