SDWebImage 加載顯示 GIF 與性能問題

SDWebImage 加載顯示 GIF 與性能問題

SDWebImage 4.0 之前斋配,可以用 UIImageView 顯示 GIF 圖雷厂。如果 SDWebImage 4.0 還這么做杂拨,只會(huì)顯示靜態(tài)圖锡凝。SDWebImage 4.0 用 FLAnimatedImageView 通過 FLAnimatedImage 顯示 GIF 圖杉女。本文的這兩個(gè)庫的版本分別為 SDWebImage 4.0.0 和 FLAnimatedImage 1.0.12贰剥。

CocoaPods 安裝

pod'SDWebImage'pod'SDWebImage/GIF'

一般用法

用 FLAnimatedImageView 代替 UIImageView倾剿,顯示 GIF。FLAnimatedImage 的 README.md 中介紹的用法


FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:[NSDatadataWithContentsOfURL:[NSURLURLWithString:@"https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"]]];

FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];

imageView.animatedImage = image;imageView.frame =CGRectMake(0.0,0.0,100.0,100.0);[self.view addSubview:imageView];

千萬別這么寫蚌成,這段代碼會(huì)阻塞主線程前痘!在主線程通過 URL 獲取 NSData,等下載結(jié)束才執(zhí)行下一步担忧。

FLAnimatedImageView 的用法和 UIImageView 相似芹缔,初始化、設(shè)置 frame瓶盛、添加到視圖上最欠、用 UIImage 給 image 屬性賦值顯示靜態(tài)圖片;不一樣的是惩猫,用 FLAnimatedImage 給 animatedImage 屬性賦值顯示動(dòng)態(tài)圖片芝硬。以上代碼的問題在于 FLAnimatedImage 的生成部分。

SDWebImage 給 FLAnimatedImageView 添加了異步加載 GIF 的方法轧房,與異步加載靜態(tài)圖片一樣

imageView.sd_setImage(with: url, placeholderImage: placeholder)

如果顯示少量的 GIF拌阴,這樣寫應(yīng)該可以。然而奶镶,如果需要用 UITableView 或 UICollectionView 展示大量 GIF迟赃,這么寫可能會(huì)有性能問題,滑動(dòng)時(shí)發(fā)生頓卡厂镇。

提升性能

為了提高性能纤壁,可以指定 RunLoopMode,在 default mode 進(jìn)行動(dòng)畫捺信,在 tracking mode (比如 scroll view 滑動(dòng)時(shí)) 停止動(dòng)畫

imageView.runLoopMode =RunLoopMode.defaultRunLoopMode.rawValue

我的代碼中酌媒,這么寫還是會(huì)有頓卡。查看 SDWebImage 的源碼残黑,發(fā)現(xiàn)了問題馍佑。

sd_setImage(with:placeholderImage:) 會(huì)調(diào)用 sd_internalSetImageWithURL: 方法

注意,sd_internalSetImageWithURL: 方法中的 setImageBlock 參數(shù)梨水,在此生成 FLAnimatedImage拭荤。進(jìn)一步查看 sd_internalSetImageWithURL: 方法的實(shí)現(xiàn)

宏定義 dispatch_main_async_safe(block) 保證 block 在主線程中執(zhí)行,其中包含 setImageBlock疫诽。因此 setImageBlock 在主線程中執(zhí)行舅世,也就是說 FLAnimatedImage 在主線程中生成旦委,這一步比較耗時(shí),阻塞主線程雏亚,造成頓卡缨硝。

解決辦法是,把 FLAnimatedImage 的生成放到子線程中罢低〔楸纾可以直接修改 SDWebImage 的源碼,但不建議這么做网持。比較好的辦法是宜岛,給 FLAnimatedImageView 添加方法

extension FLAnimatedImageView{

funcsetImage(with url: URL?, placeholderImage: UIImage?){? ? ? ? sd_internalSetImage(with: url, placeholderImage: placeholderImage, options:SDWebImageOptions(rawValue:0), operationKey:nil, setImageBlock: { [weakself] (image, imageData)inguardletstrongSelf =selfelse{return}letimageFormat =NSData.sd_imageFormat(forImageData: imageData)ifimageFormat == .GIF{// Enter global queueDispatchQueue.global(qos: .userInteractive).async { [weakself]in// Create FLAnimatedImage in global queueletanimatedImage =FLAnimatedImage(animatedGIFData: imageData)DispatchQueue.main.async { [weakself]inguardletstrongSelf =selfelse{return}// Set image in main queuestrongSelf.animatedImage = animatedImage? ? ? ? ? ? ? ? ? ? ? ? strongSelf.image =nil}? ? ? ? ? ? ? ? }? ? ? ? ? ? }else{// Set image in main queuestrongSelf.image = image? ? ? ? ? ? ? ? strongSelf.animatedImage =nil}? ? ? ? ? ? }, progress:nil, completed:nil)? ? }}

同樣調(diào)用 sd_internalSetImageWithURL: 方法,只是修改 setImageBlock 參數(shù)功舀,在子線程中創(chuàng)建 FLAnimatedImage萍倡,然后在主線程中設(shè)置圖片。

這個(gè)方法也適用于靜態(tài)圖片辟汰。如果圖片是靜態(tài)圖片列敲,直接在主線程中設(shè)置圖片,不用進(jìn)入子線程帖汞。

調(diào)用這個(gè)方法很簡單

imageView.setImage(with: url, placeholderImage: placeholder)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末戴而,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子涨冀,更是在濱河造成了極大的恐慌填硕,老刑警劉巖麦萤,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹿鳖,死亡現(xiàn)場離奇詭異,居然都是意外死亡壮莹,警方通過查閱死者的電腦和手機(jī)翅帜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來命满,“玉大人涝滴,你說我怎么就攤上這事〗禾ǎ” “怎么了歼疮?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長诈唬。 經(jīng)常有香客問我韩脏,道長,這世上最難降的妖魔是什么铸磅? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任赡矢,我火速辦了婚禮杭朱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吹散。我一直安慰自己弧械,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布空民。 她就那樣靜靜地躺著刃唐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪界轩。 梳的紋絲不亂的頭發(fā)上唁桩,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音耸棒,去河邊找鬼荒澡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛与殃,可吹牛的內(nèi)容都是我干的单山。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼幅疼,長吁一口氣:“原來是場噩夢啊……” “哼米奸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起爽篷,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤悴晰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后逐工,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铡溪,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年泪喊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了棕硫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡袒啼,死狀恐怖哈扮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蚓再,我是刑警寧澤滑肉,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站摘仅,受9級(jí)特大地震影響靶庙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜实檀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一惶洲、第九天 我趴在偏房一處隱蔽的房頂上張望按声。 院中可真熱鬧,春花似錦恬吕、人聲如沸签则。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渐裂。三九已至,卻和暖如春钠惩,著一層夾襖步出監(jiān)牢的瞬間柒凉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工篓跛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留膝捞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓愧沟,卻偏偏與公主長得像蔬咬,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子沐寺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345