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];