YYKit

YYWebImage:
1恶复、相比SDWebImage播放gif圖片時(shí)內(nèi)存占用大大降低。
SDWebImage中對(duì)gif的圖片處理是,將gif圖片的每一幀存放到數(shù)組之中朽色,在賦值給UIImageView對(duì)象播放動(dòng)畫。注意组题,此時(shí)存放在數(shù)組中的UIImage對(duì)象并未解碼占用內(nèi)存空間葫男,而要等到具體在屏幕上播放時(shí)才會(huì)解碼。例如一個(gè)gif圖片有100幀崔列,采用UIImageView播放時(shí)梢褐,可以觀察到隨著播放的進(jìn)行內(nèi)存不斷增加,直至一個(gè)循環(huán)播放完成。因?yàn)閁IImageView強(qiáng)引用數(shù)組對(duì)象盈咳,數(shù)組中的對(duì)象隨著播放的進(jìn)行不斷解碼占用巨大內(nèi)存空間而無(wú)法釋放趣效,容易導(dǎo)致內(nèi)存爆炸。
YYWebImage中播放gif圖片猪贪,采用的是定時(shí)器策略跷敬。YYAnimatedImageView是UIImageView的子類。用字典將gif圖片的每一幀緩存起來(lái)热押,緩存格式為

@{
  @1: UIImage,
  @2: UIImage.....
}

利用CADisplayLink定時(shí)器不斷改變索引值1西傀、2、3桶癣,從緩存字典中取出對(duì)應(yīng)的UIImage對(duì)象拥褂,賦值給YYAnimatedImageView的layer.contents屬性,從而生成動(dòng)畫牙寞。因?yàn)榫彺孀值鋵?duì)象內(nèi)部的UIImage都沒(méi)有解碼饺鹃,所以沒(méi)有內(nèi)存爆炸問(wèn)題。
以上解釋有誤间雀,以下面為準(zhǔn)
SDWebImage將gif資源中的每一張image寫入到內(nèi)存中悔详,通過(guò)animatedImageWithImages的方式播放動(dòng)畫,這樣做的好處是gif輪播時(shí)直接從內(nèi)存中讀取資源就好惹挟,降低了CPU的使用茄螃,以空間換取流暢度,但是這也會(huì)導(dǎo)致當(dāng)同時(shí)加載的gif數(shù)量增加時(shí)內(nèi)存問(wèn)題暴露的尤其明顯连锯。因?yàn)椴シ艜r(shí)間采用的是總時(shí)間归苍,每張圖片播放的都是平均時(shí)間,播放效果差运怖。
YYWebImage采用NSOperation后臺(tái)線程解壓圖片并緩存拼弃,用定時(shí)器從緩存中讀取圖片實(shí)現(xiàn)gif圖片播放。這必然需要消耗CPU摇展,所以YYWebImage相比較SDWebImage更消耗CPU吻氧。根據(jù)內(nèi)存使用情況控制緩存圖片字典數(shù)據(jù)量控制內(nèi)存,內(nèi)存得到控制吗购。因?yàn)橛枚〞r(shí)器医男,每個(gè)圖片播放時(shí)間基本就是gif中所占用的時(shí)間,播放效果好捻勉。

2镀梭、實(shí)現(xiàn)隔行掃描interlaced,在圖片未下載完成時(shí)顯示更好的效果
在下載圖片時(shí)踱启,首先用 CGImageSourceCreateIncremental(NULL) 創(chuàng)建一個(gè)空的圖片源报账,隨后在獲得新數(shù)據(jù)時(shí)調(diào)用CGImageSourceUpdateData(data, false) 來(lái)更新圖片源研底,最后在用 CGImageSourceCreateImageAtIndex() 創(chuàng)建圖片來(lái)顯示。SDWebImage未采用此方法解壓圖片透罢,圖片下載完成后顯示很突兀榜晦,效果差。

3羽圃、圖片為何在顯示前都要進(jìn)行解碼操作乾胶?
各個(gè)圖片框架在下載完圖片后都會(huì)在后臺(tái)線程進(jìn)行解碼操作,但是不解碼圖片也是能正常顯示的朽寞,原因是系統(tǒng)會(huì)在圖片顯示的時(shí)候自動(dòng)解碼识窿。框架事先在子線程解碼能避免系統(tǒng)自動(dòng)的在主線程解碼操作脑融,由此可能會(huì)導(dǎo)致的主線程堵塞喻频,閃圖等現(xiàn)象。
事先將圖片解碼肘迎,會(huì)導(dǎo)致圖片的內(nèi)存占用大大增加甥温。框架又都會(huì)有內(nèi)存和磁盤緩存妓布,對(duì)大圖片姻蚓,有可能存在內(nèi)存太大,甚至來(lái)不及釋放內(nèi)存導(dǎo)致的閃退現(xiàn)象秋茫,可如下方法解決史简。

  • 對(duì)大圖片禁止事先解壓操作,框架都考慮了這一點(diǎn)肛著,有個(gè)屬性設(shè)置為NO即可。
  • 圖片內(nèi)存大跟圖片的尺寸有關(guān)跺讯,可以在解壓前先將圖片等比例壓縮枢贿,占用空間會(huì)大大縮小。
  • 手動(dòng)清空內(nèi)存緩存刀脏,設(shè)置內(nèi)存緩存最大容量等

YYModel:
1局荚、為何效率很高?

  • 因?yàn)槟P偷慕Y(jié)構(gòu)一般是固定的愈污,緩存了運(yùn)行時(shí)獲取模型類以及父類的所有屬性(property耀态、method、setter/getter暂雹、type等)首装。
  • 采用枚舉獲取屬性修飾符(strong等)和type(NSArray等),相比NSScanner效率更高杭跪。
  • 調(diào)用model的setter為每一個(gè)屬性賦值仙逻,性能比KVC要高驰吓。
  • 大量使用CF框架函數(shù),性能更佳系奉。
  • 使用dispatch_semaphore_t保證線程安全

YYCache:
1檬贰、內(nèi)存緩存
雙向鏈表和CFMutableDictionaryRef配合存儲(chǔ),前者處理順序缺亮,后者處理查詢翁涤。實(shí)現(xiàn)LRU算法,優(yōu)先淘汰使用時(shí)間最早的節(jié)點(diǎn)萌踱、即鏈表末尾的數(shù)據(jù)迷雪。例如依次有A、B虫蝶、C章咧、D四個(gè)數(shù)據(jù),當(dāng)查詢C的時(shí)候能真,CFMutableDictionaryRef保證最快的查詢速度赁严,鏈表保證最快的移動(dòng)速度將C移動(dòng)至head,兩者配合天衣無(wú)縫粉铐。
當(dāng)內(nèi)存報(bào)警或者用戶退到后臺(tái)疼约,采用子線程釋放對(duì)象技術(shù)清理緩存數(shù)據(jù),該技術(shù)原理如下

- (void)viewDidLoad {
    [super viewDidLoad];
    Person *p = [Person new];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
       [p class]
    });
}

如上蝙泼,正常情況下p對(duì)象會(huì)在主線程釋放程剥,但是若用子線程block捕獲p對(duì)象,則viewDidLoad執(zhí)行完后block為最后一個(gè)擁有p的場(chǎng)所汤踏,p會(huì)在子線程runloop運(yùn)行結(jié)束時(shí)釋放织鲸,達(dá)到了對(duì)象在子線程釋放的目的,避免主線程資源占用溪胶。

2频祝、磁盤緩存
小文件(默認(rèn)是小于20kb)采用sqlite绞吁,大文件采用歸檔后寫文件的方式存儲(chǔ)棕所,效率最高擂啥。值得一提的是對(duì)sqlite語(yǔ)句做了緩存

- (sqlite3_stmt *)_dbPrepareStmt:(NSString *)sql {
    if (![self _dbCheck] || sql.length == 0 || !_dbStmtCache) return NULL;
    // 從_dbStmtCache取出已緩存的sqlite3_stmt
    sqlite3_stmt *stmt = (sqlite3_stmt *)CFDictionaryGetValue(_dbStmtCache, (__bridge const void *)(sql));
    if (!stmt) {
        // 沒(méi)有緩存再創(chuàng)建
       sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL);
        // 緩存
        CFDictionarySetValue(_dbStmtCache, (__bridge const void *)(sql), stmt);
    } else {
        sqlite3_reset(stmt);
    }
    return stmt;
}

sqlite3_stmt: 該對(duì)象的表示已經(jīng)編譯成二進(jìn)制形式并準(zhǔn)備執(zhí)行的單個(gè) SQL 語(yǔ)句。緩存了這個(gè)才避,可以避免sql語(yǔ)句重復(fù)生成該可執(zhí)行語(yǔ)句的開銷橱夭,性能優(yōu)化。
對(duì)大文件桑逝,采用的是文件整體部分用寫文件方式保存棘劣,而配合用sqlite保存該文件的基礎(chǔ)信息,比如文件路徑肢娘、文件大小呈础、保存時(shí)間等舆驶。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市而钞,隨后出現(xiàn)的幾起案子沙廉,更是在濱河造成了極大的恐慌,老刑警劉巖臼节,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撬陵,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡网缝,警方通過(guò)查閱死者的電腦和手機(jī)巨税,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)粉臊,“玉大人草添,你說(shuō)我怎么就攤上這事《笾伲” “怎么了远寸?”我有些...
    開封第一講書人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)屠凶。 經(jīng)常有香客問(wèn)我驰后,道長(zhǎng),這世上最難降的妖魔是什么矗愧? 我笑而不...
    開封第一講書人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任灶芝,我火速辦了婚禮,結(jié)果婚禮上唉韭,老公的妹妹穿的比我還像新娘夜涕。我一直安慰自己,他們只是感情好纽哥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開白布钠乏。 她就那樣靜靜地躺著,像睡著了一般春塌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上簇捍,一...
    開封第一講書人閱讀 51,231評(píng)論 1 299
  • 那天只壳,我揣著相機(jī)與錄音,去河邊找鬼暑塑。 笑死吼句,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的事格。 我是一名探鬼主播惕艳,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼搞隐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了远搪?” 一聲冷哼從身側(cè)響起劣纲,我...
    開封第一講書人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谁鳍,沒(méi)想到半個(gè)月后癞季,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡倘潜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年绷柒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涮因。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡废睦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出养泡,到底是詐尸還是另有隱情嗜湃,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布瓤荔,位于F島的核電站净蚤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏输硝。R本人自食惡果不足惜今瀑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望点把。 院中可真熱鬧橘荠,春花似錦、人聲如沸郎逃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)褒翰。三九已至贮懈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間优训,已是汗流浹背朵你。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留揣非,地道東北人抡医。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像早敬,于是被迫代替她去往敵國(guó)和親忌傻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子大脉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,085評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件水孩、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,096評(píng)論 4 62
  • 【六】神馬公主抱 下午四點(diǎn)镰矿,等候了多時(shí)的警察們終于等到夏溪帶貨出門了。 一群牲口全副武裝荷愕,準(zhǔn)備將威爾遜拿下衡怀。 只有...
    冬華閱讀 1,918評(píng)論 1 3
  • “春天來(lái)了屈嗤,大地蘇醒,又到一年中交配的季節(jié)——” 哦吊输!不對(duì)饶号! “又到了一年中減肥的季節(jié)......” 有句老話不是...
    黃小N閱讀 261評(píng)論 0 3
  • 前兩天,我認(rèn)識(shí)一個(gè)六年的朋友季蚂,她直播我過(guò)去玩茫船,我說(shuō),幾年過(guò)去了扭屁,我們當(dāng)中就剩你媳婦和你算谈,我見(jiàn)證你們從喜歡到相...
    一只可愛(ài)的金牛座閱讀 287評(píng)論 0 2