iOS開發(fā)內存優(yōu)化之SDWebImage內存占用過高

最近在做APP的Memory優(yōu)化,網上一大堆優(yōu)化方案,也比較全面

比如:
iOS開發(fā)-18個性能優(yōu)化/內存優(yōu)化常用方法(很常用)
iOS 25個性能優(yōu)化/內存優(yōu)化常用方法
等等。。。也有很多重復的文章。

但是試了一大半感覺優(yōu)化的很不明顯,于是使用Instruments檢測了一下:


21_313021_80f3a1d3bdfeefc.png

圖片是找到的,實際中當然沒有內存泄漏,但是消耗大量內存卻指向了同一個地方。

查找了大量資料后發(fā)現問題出在對高分辨率圖片的處理上

下面有三種方法可以參考:

第一種
使用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;
    
    // 創(chuàng)建一個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中創(chuàng)建一個改變大小后的圖片
    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];     // 壓縮過大的圖片數據
        }
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容