1. 網路圖片顯示大體步驟:
下載圖片
圖片處理(裁剪,邊框等)
寫入磁碟
從磁碟讀取資料到核心緩衝區
從核心緩衝區複製到使用者空間(記憶體級別拷貝)
解壓縮為點陣圖(耗cpu較高)
如果點陣圖資料不是位元組對齊的,CoreAnimation
另外一種解決方案是:
imageView物件和圖片的url相關聯,在滑動時,不取消舊的下載任務,而是在下載任務完成回撥時,進行url匹配,只有匹配成功的image會重新整理imageView物件,而其他的image則只做快取操作,而不重新整理UI。
同時,仍然管理一個執行佇列,為了避免佔用太多的資源,通常會對執行佇列設定一個最大的併發量。此外,為了保證LIFO
2.3 關於位元組對齊
SDWebImage與AFNetworking都沒有對第7點做優化,FastImageCache相對與其他的開源庫,則對第5點與第7點做了優化。這裡我們談談第七點,關於圖片資料的位元組對齊。
Core Animation在某些情況下渲染前會先拷貝一份影象資料,通常是在影象資料非位元組對齊的情況下會進行拷貝處理,官方文件沒有對這次拷貝行為作說明,模擬器和Instrument裡有高亮顯示“copied images”的功能,但似乎它有bug,即使某張圖片沒有被高亮顯示出渲染時被copy,從呼叫堆疊上也還是能看到呼叫了CA::Render::copy_image方法:
那什麼是位元組對齊呢,按我的理解,為了效能,底層渲染影象時不是一個畫素一個畫素渲染,而是一塊一塊渲染,資料是一塊塊地取,就可能遇到這一塊連續的記憶體資料裡結尾的資料不是影象的內容,是記憶體裡其他的資料,可能越界讀取導致一些奇怪的東西混入,所以在渲染之前CoreAnimation要把資料拷貝一份進行處理,確保每一塊都是影象資料,對於不足一塊的資料置空。大致圖示:(pixel是影象畫素資料,data是記憶體裡其他資料)
塊的大小應該是跟CPU cache line有關,ARMv7是32byte,A9是64byte,在A9下CoreAnimation應該是按64byte作為一塊資料去讀取和渲染,讓影象資料對齊64byte就可以避免CoreAnimation再拷貝一份資料進行修補。FastImageCache做的位元組對齊就是這個事情。
從程式碼上來看,主要是在建立上圖解碼的過程中,CGBitmapContextCreate
2.6 其他(諸如圖片預下載,gif支援等等,下載進度條)
待補充
3. 常用的開源庫對比
tip | SDWebImage | AFNetworking | FastImageCache |
---|---|---|---|
非同步下載圖片 | YES | YES | NO |
子執行緒解壓縮 | YES | YES | YES |
子執行緒圖片處理(縮放,圓角等) | YES | YES | YES |
儲存解壓縮後的點陣圖 | YES | YES | YES |
記憶體級別快取 | YES | YES | YES |
磁碟級別快取 | YES | YES | YES |
UIImageView category | YES | NO | NO |
減少記憶體級別的拷貝 | NO | NO | YES |
介面易用性 | *** | *** | * |
參考資料
FastImageCache-github
SDWebImage-github
File System vs Core Data: the image cache test
iOS image caching. Libraries benchmark (SDWebImage vs FastImageCache)
Avoiding Image Decompression Sickness
iOS圖片載入速度極限優化—FastImageCache解析
轉載請註明出處哦,我的部落格: luoyibu
写评论
很抱歉,必須登入網站才能發佈留言。