美文网首页
SDWebImage加载多个大图导致内存泄漏崩溃

SDWebImage加载多个大图导致内存泄漏崩溃

作者: 远航Yang | 来源:发表于2017-10-16 09:11 被阅读0次

SDWebImage是iOS开发者加载网络图片比较常用的开源框架,高效的缓存机制,加载根据缓存取出相对应图片解压展示,使用户用起来是非常顺畅的。但是我在做图片轮播的时候,遇到了用户上传了多张大图的时候,大概每张小于1M的,我连续加载几个相同的页面,我看到XCode的使用内存从20M飙升到500M,接着didReceiveMemoryWarning断点了,内存泄漏,接着程序奔溃了。由于之前一直听说SDWebImage加载大图会奔溃的问题,所以这次遇到,我直接找SDWebImage的问题的。

1、直接在UIImage+MultiFormat添加图片压缩方法,根据屏幕比例,分辨率来压缩图片

+(UIImage*)compressImageWith:(UIImage*)image

{

floatimageWidth = image.size.width;

floatimageHeight = image.size.height;

floatwidth =640;

floatheight = image.size.height/(image.size.width/width);

floatwidthScale = imageWidth /width;

floatheightScale = imageHeight /height;

// 创建一个bitmap的context

// 并把它设置成为当前正在使用的context

if([[UIScreenmainScreen]scale] ==2.0){

UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height),NO,2.0);

}elseif([[UIScreenmainScreen]scale] ==3.0){

UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height),NO,3.0);

}

else{

UIGraphicsBeginImageContext(CGSizeMake(width, height));

}

if(widthScale > heightScale) {

[imagedrawInRect:CGRectMake(0,0, imageWidth /heightScale , height)];

}

else{

[imagedrawInRect:CGRectMake(0,0, width , imageHeight /widthScale)];

}

// 从当前context中创建一个改变大小后的图片

UIImage*newImage =UIGraphicsGetImageFromCurrentImageContext();

// 使当前的context出堆栈

UIGraphicsEndImageContext();

returnnewImage;

}

2、在UIImage+MultiFormat原有的方法sd_imageWithData中调用compressImageWith方法

+ (UIImage*)sd_imageWithData:(NSData*)data {

if(!data) {

returnnil;

}

UIImage*image;

NSString*imageContentType = [NSDatasd_contentTypeForImageData:data];

if([imageContentTypeisEqualToString:@"image/gif"]) {

image = [UIImagesd_animatedGIFWithData:data];

}

#ifdef SD_WEBP

elseif([imageContentType isEqualToString:@"image/webp"])

{

image = [UIImage sd_imageWithWebPData:data];

}

#endif

else{

image = [[UIImagealloc]initWithData:data];

if(data.length/1024>128) {

image = [selfcompressImageWith:image];

}

UIImageOrientationorientation = [selfsd_imageOrientationFromImageData:data];

if(orientation !=UIImageOrientationUp) {

image = [UIImageimageWithCGImage:image.CGImage

scale:image.scale

orientation:orientation];

}

}

returnimage;

}

3、最后一步,在SDWebImageDownloaderOperation的connectionDidFinishLoading添加根据判断图片类型进行压缩

if(self.options&SDWebImageDownloaderIgnoreCachedResponse&&responseFromCached) {

completionBlock(nil,nil,nil,YES);

}elseif(self.imageData) {

UIImage*image = [UIImagesd_imageWithData:self.imageData];

NSString*key = [[SDWebImageManagersharedManager]cacheKeyForURL:self.request.URL];

image = [selfscaledImageForKey:keyimage:image];

//自己添加

NSPUIImageTypeimageType =NSPUIImageTypeFromData(self.imageData);

if(imageType ==NSPUIImageType_PNG) {

NSData*data =UIImagePNGRepresentation(image);

self.imageData= [NSMutableDatadataWithData:data];

}elseif(imageType ==NSPUIImageType_JPEG) {

NSData*data =UIImageJPEGRepresentation(image,1);

self.imageData= [NSMutableDatadataWithData:data];

}

//判断图片格式内联方法

/*

typedef NS_ENUM(NSInteger, NSPUIImageType) {

NSPUIImageType_JPEG,

NSPUIImageType_PNG,

NSPUIImageType_Unknown

};*/

staticinlineNSPUIImageTypeNSPUIImageTypeFromData(NSData*imageData)

{

if(imageData.length>4) {

constunsignedchar*bytes = [imageDatabytes];

if(bytes[0] ==0xff&&

bytes[1] ==0xd8&&

bytes[2] ==0xff)

{

returnNSPUIImageType_JPEG;

}

if(bytes[0] ==0x89&&

bytes[1] ==0x50&&

bytes[2] ==0x4e&&

bytes[3] ==0x47)

{

returnNSPUIImageType_PNG;

}

}

returnNSPUIImageType_Unknown;

}

添加完毕,再来看看内存,明显感觉内存使用小很多了,解决完毕。

相关文章

网友评论

      本文标题:SDWebImage加载多个大图导致内存泄漏崩溃

      本文链接:https://www.haomeiwen.com/subject/nlahuxtx.html