SDWebImage加載.gif 內(nèi)存狂飆問題

于之前一直維護新浪博客,大量的東西都在這里捡偏,實在不想更換其他博客了唤冈,怎奈新浪對代碼的排版,蛋疼至極银伟,我盡量排版清晰些你虹;

閑著沒事,嘗試用SD加載 .jif,在Cell里加載了大量的.jif,加載完成后意外出現(xiàn)了彤避,內(nèi)存狂飆到 700M+傅物,滑動Cell會下降,大概到150M左右(所用的 .jif 本身比較大)忠藤; 這個不能忍挟伙,于是各種解決:
在測試過程中發(fā)現(xiàn)SD 對混合圖層的處理也不是很到位;不管是動態(tài)圖還是靜態(tài)圖模孩,都未做混合圖層處理;

順便提一下混合圖層:
Color Copied Images:該選項可以給繪制時被Core Animation復(fù)制的圖片添加藍綠色疊加層
Color Misaligned Images:如果圖片邊界沒有與目標(biāo)像素完美對齊贮缅,該功能可為圖片疊加上一層品紅色榨咐。如果圖
片使用確定的比例大小繪制,那么該功能會為圖片添加一層黃色疊加谴供。

原因概述: SD在對 .jif 的處理過程中采用了一個數(shù)組存儲 jif 的幀圖片块茁,然而并沒有及時釋放;注意文中標(biāo)注”
“的地方桂肌;
解決方案: 1. 采用YY_WebImage框架数焊,
2. 在使用SDWebImage加載較多圖片造成內(nèi)存警告時,定期調(diào)用 [[SDImageCache sharedImageCache] setValue:nil forKey:@"memCache"]; 比如tableView加載更多的時候崎场;

這里只介紹方案二:

1.首先分析SD加載 jif 的過程:
sd_animatedGIFNamed是SDWebImage提供的加載gif圖片的一種方法佩耳。我們點進去這個方法去看以下。

sd_animatedGIFNamed 這個方法的實現(xiàn)如下谭跨。生成一個UIImage對象干厚。

  • (UIImage *)sd_animatedGIFNamed:(NSString *)name {
    //取到屏幕分辨率
    CGFloat scale = [UIScreen mainScreen].scale;
    //是否是高清屏
    if (scale > 1.0f) {
    //如果是高清屏 取@2x圖片 讀取圖片
    NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name
    stringByAppendingString:@"@2x"] ofType:@"gif"];
    //圖片轉(zhuǎn)換為
    data NSData *data = [NSData dataWithContentsOfFile:retinaPath];
    //如果圖片存在
    if (data) {
    //調(diào)用sd_animatedGIFWithData 生成image實例
    return [UIImage sd_animatedGIFWithData:data]; }
    //如果@2x圖片不存在 讀取普通圖片
    NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];
    //圖片轉(zhuǎn)換為
    data data = [NSData dataWithContentsOfFile:path];
    //如果圖片存在
    if (data) {
    //調(diào)用sd_animatedGIFWithData 生成image實例
    return [UIImage sd_animatedGIFWithData:data]; }
    //如果圖片不存在
    return [UIImage imageNamed:name]; }
    else { //如果不是高清屏 讀取普通圖片
    NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; //圖片轉(zhuǎn)換為data
    NSData *data = [NSData dataWithContentsOfFile:path];
    //如果圖片存在
    if (data) {
    //調(diào)用sd_animatedGIFWithData 生成image實例
    return [UIImage sd_animatedGIFWithData:data]; }
    //如果圖片不存在
    return [UIImage imageNamed:name]; } }

注釋已經(jīng)很詳細了,這個類方法里面主要是確定當(dāng)前設(shè)備的分辨率螃宙,以便加載不同分辨率的圖片蛮瞄。
然后通過sd_animatedGIFWithData 后續(xù)處理
2.再來看看sd_animatedGIFWithData:

  • (UIImage *)sd_animatedGIFWithData:(NSData *)data {
    if (!data) {
    return nil; }
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    size_t count = CGImageSourceGetCount(source);
    UIImage *animatedImage;
    if (count <= 1) {
    animatedImage = [[UIImage alloc] initWithData:data];}
    else {
    // 注意這里的數(shù)組:
    NSMutableArray *images = [NSMutableArray array];
    NSTimeInterval duration = 0.0f;
    for (size_t i = 0; i < count; i++) {
    CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
    duration += [self frameDurationAtIndex:i source:source];
    // 數(shù)組不斷的添加幀圖片,然而并沒有及時釋放
    [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
    CGImageRelease(image); }
    if (!duration) {
    duration = (1.0f / 10.0f) * count; }
    animatedImage = [UIImage animatedImageWithImages:images duration:duration]; }
    CFRelease(source); return animatedImage; }
    先看這行代碼
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    CGImageSourceRef定義如下谆扎,
      typedef struct CGImageSource *CGImageSourceRef;
    可以看到它是一個CGImageSource 指針挂捅。
    CGImageSource是個什么東東呢?
    CGImageSource是對圖像數(shù)據(jù)讀取任務(wù)的抽象堂湖,通過它可以獲得圖像對象闲先、縮略圖状土、圖像的屬性(包括Exif信息)。
    那么這行代碼可以這樣理解:通過nadata取到圖像的以系列信息饵蒂。
    再看size_t count = CGImageSourceGetCount(source);
    這行代碼是讀取CGImageSourceRef有幾個圖片對象声诸。
    下面就不難理解了,
    CGImageSourceCreateImageAtIndex :從source里面讀取各個圖片放入數(shù)組里面退盯。
    讀取顯示圖片的 時間:
    duration += [self frameDurationAtIndex:i source:source];
    計算圖片顯示時間:
  • (float)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source { float frameDuration = 0.1f;
    CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
    NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
    NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];
    NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
    if (delayTimeUnclampedProp) {
    frameDuration = [delayTimeUnclampedProp floatValue]; }
    else {
    NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
    if (delayTimeProp) {
    frameDuration = [delayTimeProp floatValue]; } }
    if (frameDuration < 0.011f) {
    frameDuration = 0.100f; }
    CFRelease(cfFrameProperties); return frameDuration;
    }
    最后:
    從數(shù)組中讀取幀圖片并顯示:
    animatedImage = [UIImage animatedImageWithImages:images duration:duration];
    播放數(shù)組里里面的圖片彼乌。
    從以上分析中可以知道: SD在處理 jif 的時候 采用數(shù)組暫存了 jif 的幀圖片,并未及時釋放渊迁,最終導(dǎo)致內(nèi)存飆升問題慰照;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市琉朽,隨后出現(xiàn)的幾起案子毒租,更是在濱河造成了極大的恐慌,老刑警劉巖箱叁,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件墅垮,死亡現(xiàn)場離奇詭異,居然都是意外死亡耕漱,警方通過查閱死者的電腦和手機算色,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來螟够,“玉大人灾梦,你說我怎么就攤上這事〖梭希” “怎么了若河?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長寞宫。 經(jīng)常有香客問我萧福,道長,這世上最難降的妖魔是什么淆九? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任统锤,我火速辦了婚禮,結(jié)果婚禮上炭庙,老公的妹妹穿的比我還像新娘饲窿。我一直安慰自己,他們只是感情好焕蹄,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布逾雄。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鸦泳。 梳的紋絲不亂的頭發(fā)上银锻,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音做鹰,去河邊找鬼击纬。 笑死,一個胖子當(dāng)著我的面吹牛钾麸,可吹牛的內(nèi)容都是我干的更振。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼饭尝,長吁一口氣:“原來是場噩夢啊……” “哼肯腕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钥平,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤师枣,失蹤者是張志新(化名)和其女友劉穎罐韩,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嵌施,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡绎晃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年出革,在試婚紗的時候發(fā)現(xiàn)自己被綠了厨幻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹄溉。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖囚巴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情友扰,我是刑警寧澤彤叉,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站村怪,受9級特大地震影響秽浇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜甚负,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一柬焕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梭域,春花似錦斑举、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春赎懦,著一層夾襖步出監(jiān)牢的瞬間雀鹃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工励两, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留黎茎,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓当悔,卻偏偏與公主長得像傅瞻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子先鱼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容