SDWebImage是iOS開發(fā)者加載網(wǎng)絡(luò)圖片比較常用的開源框架,高效的緩存機(jī)制淘衙,加載根據(jù)緩存取出相對應(yīng)圖片解壓展示,使用戶用起來是非常順暢的彤守。但是我在做圖片輪播的時候,遇到了用戶上傳了多張大圖的時候具垫,大概每張小于1M的,我連續(xù)加載幾個相同的頁面筝蚕,我看到XCode的使用內(nèi)存從20M飆升到500M,接著didReceiveMemoryWarning斷點了起宽,內(nèi)存泄漏,接著程序奔潰了坯沪。由于之前一直聽說SDWebImage加載大圖會奔潰的問題,所以這次遇到叉弦,我直接找SDWebImage的問題的。
1卸奉、直接在UIImage+MultiFormat添加圖片壓縮方法,根據(jù)屏幕比例榄棵,分辨率來壓縮圖片
+(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;
// 創(chuàng)建一個bitmap的context
// 并把它設(shè)置成為當(dāng)前正在使用的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)];
}
// 從當(dāng)前context中創(chuàng)建一個改變大小后的圖片
UIImage*newImage =UIGraphicsGetImageFromCurrentImageContext();
// 使當(dāng)前的context出堆棧
UIGraphicsEndImageContext();
returnnewImage;
}
2、在UIImage+MultiFormat原有的方法sd_imageWithData中調(diào)用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添加根據(jù)判斷圖片類型進(jìn)行壓縮
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];
}
//判斷圖片格式內(nèi)聯(lián)方法
/*
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;
}
添加完畢垫蛆,再來看看內(nèi)存腺怯,明顯感覺內(nèi)存使用小很多了袱饭,解決完畢呛占。