SDWebImage加載多個大圖導致內存泄漏崩潰

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;

}

添加完畢,再來看看內存,明顯感覺內存使用小很多了,解決完畢。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容