转载: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方法
发现这里面对图片的处理是直接按照原大小进行的,如果几千是分辨率这里导致占用了大量内存!

所以我们需要在这里对图片做一次等比压缩
我们在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;
}
再在上面箭头代码后面对图片进行压缩!

到了这里还需进行最后一步,就是在SDWebImageDownloadOperation的connectionDidFinishLoading方法里面的:
UIImage *image = [UIImage sd_imageWithData:self.imageData];
添加后面代码
NSData *data = UIImageJPEGRepresentation(image, 1);
self.imageData = [NSMutableData dataWithData:data];
就是这样子

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

大功告成!亲测内存变化不大,自动释放也来得及。
关闭打赏,仅作学习!
网友评论