iOS最全图片内存优化

2018-07-30  本文已影响416人  遛遛食

在加载大量图片的时候,尤其是一些高清大图的时候如果不做什么处理,很容易导致APP内存溢出,软件闪退的问题。
在加载图片的时候,我们一般使用SDWebimage框架,所以,下面的处理方法,我们也是以SDWebimage框架来处理。

清理缓存

最简单的一个操作就是监听tableView的滚动事件,当进行了滚动的时候进行缓存的清理来减少内存。

[[SDWebImageManager sharedManager].imageCache clearMemory];

[[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"];//建议使用这句话,效果更好

更改图片加载方式

我们一般加载本地图片的时候都是使用图片的名称来加载图片,但是这种加载方式会先把图片加载到内存中,所以如果图片很大的话,就会影响到内存,所以,建议使用NSData的方法来加载图片。

[UIImage imageNamed:ImageName];
//更换为
NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
NSData *image = [NSData dataWithContentsOfFile:filePath];
[UIImage imageWithData:image];

进行缓存清理

监听scrollView的滚动事件,一旦滚动就清理缓存

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    [[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"];
}

监听内存警告,一旦收到内存警告就清理缓存

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    [[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"];
}

减少图片体积

内存溢出的主要原因是因为图片体积过大,所以,我们可以减少图片的体积来达到减少内存的溢出

方法一:

把图片转为jpg格式,并且压缩图片像素,会导致图片模糊,CPU使用上升,但是内存会下降。

NSData *imageData = UIImageJPEGRepresentation(image, 0.5);//取值范围0~1
UIImage *ipgImage = [UIImage imageWithData:imageData];
方法二:

在SDWebimage中修改下载的图片体积,SDWebimageManager.m文件中添加如下代码,会导致图片模糊,CPU使用上升,但是内存会下降。

-(UIImage *)compressImageWith:(UIImage *)image
{
    float imageWidth = image.size.width;
    float imageHeight = image.size.height;
    CGSize croppedSize;
    CGFloat offsetX = 0.0;
    CGFloat offsetY = 0.0;
    if (imageWidth > imageHeight) {
        offsetX = (imageWidth -imageHeight) / 2;
        croppedSize = CGSizeMake(imageHeight, imageHeight);
    } else {
        offsetY = (imageHeight-imageWidth) / 2;
        croppedSize = CGSizeMake(imageWidth, imageWidth);
    }
    CGRect clippedRect = CGRectMake(offsetX, offsetY, croppedSize.width, croppedSize.height);
    CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], clippedRect);
    
    float ratio = croppedSize.width>120?120:croppedSize.width;
    CGRect rect = CGRectMake(0.0, 0.0, ratio, ratio);
    UIGraphicsBeginImageContext(rect.size);
    [[UIImage imageWithCGImage:imageRef] drawInRect:rect];
    UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CGImageRelease(imageRef);
    
    return thumbnail;
}

然后我们要让图片来进行这个减少提交操作

//在获取到内存中的图片进行体积减少操作
else if (cachedImage) {
    cachedImage = [self compressImageWith:cachedImage];//修改图片大小
    [self callCompletionBlockForOperation:strongOperation completion:completedBlock image:cachedImage data:cachedData error:nil cacheType:cacheType finished:YES url:url];
    [self safelyRemoveOperationFromRunning:strongOperation];
} else {
//在下载完成后对图片进行体积减少操作
if (downloadedImage && finished) {//修改图片大小
      [self.imageCache storeImage:downloadedImage imageData:downloadedData forKey:key toDisk:cacheOnDisk completion:nil];
    downloadedImage = [self compressImageWith:downloadedImage];
    downloadedData = [NSMutableData dataWithData:UIImageJPEGRepresentation(downloadedImage, 1)];
//                            if (self.cacheSerializer) {
//                                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
//                                    NSData *cacheData = self.cacheSerializer(downloadedImage, downloadedData, url);
//                                    [self.imageCache storeImage:downloadedImage imageData:cacheData forKey:key toDisk:cacheOnDisk completion:nil];
//                                });
//                            } else {
//                                [self.imageCache storeImage:downloadedImage imageData:downloadedData forKey:key toDisk:cacheOnDisk completion:nil];
//                            }
}
[self callCompletionBlockForOperation:strongSubOperation completion:completedBlock image:downloadedImage data:downloadedData error:nil cacheType:SDImageCacheTypeNone finished:finished url:url];
上一篇下一篇

猜你喜欢

热点阅读