最近在做APP的Memory优化,网上一大堆优化方案,也比较全面
比如:
iOS开发-18个性能优化/内存优化常用方法(很常用)
iOS 25个性能优化/内存优化常用方法
等等。。。也有很多重复的文章。
但是试了一大半感觉优化的很不明显,于是使用Instruments检测了一下:
图片是找到的,实际中当然没有内存泄漏,但是消耗大量内存却指向了同一个地方。
查找了大量资料后发现问题出在对高分辨率图片的处理上
下面有三种方法可以参考:
第一种
使用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]; // 压缩过大的图片数据
}