iOS开发内存优化之SDWebImage内存占用过高

最近在做APP的Memory优化,网上一大堆优化方案,也比较全面

比如:
iOS开发-18个性能优化/内存优化常用方法(很常用)
iOS 25个性能优化/内存优化常用方法
等等。。。也有很多重复的文章。

但是试了一大半感觉优化的很不明显,于是使用Instruments检测了一下:


iOS开发内存优化之SDWebImage内存占用过高_第1张图片
21_313021_80f3a1d3bdfeefc.png

图片是找到的,实际中当然没有内存泄漏,但是消耗大量内存却指向了同一个地方。

查找了大量资料后发现问题出在对高分辨率图片的处理上

下面有三种方法可以参考:

第一种
使用sd_setImageWithURL里的block方法,可以对image进行比例调整,压缩。
缺点也比较明显,(这里是调整图片变形问题的)


[cell.userImgView sd_setImageWithURL:[NSURL URLWithString:jiaolian.view] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
        CGSize newSize;
        
        CGImageRef imageRef = nil;
        
        if ((image.size.width / image.size.height) < 1) {
            
            newSize.width = image.size.width;
            
            newSize.height = image.size.width ;
            
            imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(0, fabs(image.size.height - newSize.height) / 2, newSize.width, newSize.height));
            
        } else {
            
            newSize.height = image.size.height;
            
            newSize.width = image.size.height * 1;
            
            imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectMake(fabs(image.size.width - newSize.width) / 2, 0, newSize.width, newSize.height));
            
        }
        
        
        cell.userImgView.image =[UIImage imageWithCGImage:imageRef];
        

    }];

第二种
对于高分辨率的图片,应该禁止解压缩操作
参考使用SDWebImage和YYImage下载高分辨率图,导致内存暴增的解决办法


[[SDImageCache sharedImageCache] setShouldDecompressImages:NO];
[[SDWebImageDownloader sharedDownloader] setShouldDecompressImages:NO];

第三种

对SDWebImage进行修改,在"UIImage+MultiFormat.m"文件中
参考完美解决SDWebImage加载多个图片内存崩溃的问题


+ (UIImage *)sd_imageWithData:(NSData *)data {
    if (!data) {
        return nil;
    }
    
    UIImage *image;
    NSString *imageContentType = [NSData sd_contentTypeForImageData:data];
    if ([imageContentType isEqualToString:@"image/gif"]) {
        image = [UIImage sd_animatedGIFWithData:data];
    }
#ifdef SD_WEBP
    else if ([imageContentType isEqualToString:@"image/webp"])
    {
        image = [UIImage sd_imageWithWebPData:data];
    }
#endif
    else {
        image = [[UIImage alloc] initWithData:data];
        UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data];
        if (orientation != UIImageOrientationUp) {
            image = [UIImage imageWithCGImage:image.CGImage
                                        scale:image.scale
                                  orientation:orientation];
        }
    }


    return image;
}

image = [[UIImage alloc] initWithData:data];
图片取出来的时候就已经巨大无比,占用了很大的内存。

在该文件中添加图片压缩方法:


+(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;
    
}

  • (UIImage *)sd_imageWithData:(NSData *)data方法中添加如下代码
        image = [[UIImage alloc] initWithData:data];
        if (data.length/1024 > 128) {
            image = [self compressImageWith:image];     // 压缩过大的图片数据
        }

你可能感兴趣的:(iOS开发内存优化之SDWebImage内存占用过高)