iOS圖片加載新框架 - FlyImage
FlyImage 整合了SDWebImage,FastImageCache,AFNetworking的優點,是一個新的性能高效、接口簡單的圖片加載框架。
特點
-
高效
-
可將多張小圖解碼后存儲到同一張大圖上,在同屏渲染多圖時,效率極高;
-
支持 mmap 內存映射,高效的I/O操作,減少一次文件拷貝操作,同時減少內存占用;
-
支持 Byte Alignment 字節對其,渲染過程中,避免執行 CA::Render::copy_image 內存操作;
-
-
接口簡單
-
支持 UIImageView , CALayer Category;
-
不用考慮小圖片尺寸,簡單的存儲和讀取接口;
-
一套方案同時解決單張大圖和多張小圖的兩種業務場景;
-
-
WebP高效的圖片壓縮方式;
-
異步下載支持下載進度Block,方便實現自定義的下載動畫;
流行框架對比
現在iOS上比較流行的兩套圖片加載框架:
-
SDWebImage 提供了從下載到渲染一整套的解決方案,同時支持Category特性,WebP格式,使用起來非常簡單;但是同屏多張小圖快速滾動時,界面就會很明顯的卡頓;
-
FastImageCache Path推出的,非常適合于小圖片的高效渲染,內部優化了I/O讀取,解碼時支持 Byte Alignment 減少內存拷貝,同時僅需一次解碼,可以說是做到了極度優化。但是FIC有兩大缺點:
-
為了精簡代碼,從1.2以后取消圖片下載功能;
-
接口非常難用,使用時還需要指定 FICImageFormat ,每個Format中的圖片size必須保持一致,同時每張圖片需要與 [FICEntity 綁定,我僅僅是想快速展示多個icon而已...
-
基于上述的分析,如果有一個圖片庫可以將兩者的優點結合在一起,那該多好! FlyImage 就是基于此想法誕生的,新的庫整合了 FastImageCache 的優化方案,同時讓接口變得更加易用。
FlyImage 可以在一個文件中繪制多張不同size的小圖片,存儲和獲取時只需要一個固定的 key ;同時將內存映射的方法應用到大圖片的顯示方案中,減少內存的拷貝次數,加快讀取速度。具體的使用方法如下:
如何使用
安裝
platform :ios, '8.0'pod 'FlyImage', '~>1.0'
使用 UIImageView/CALayer
UIImageView *iconView = [[UIImageView alloc] initWithFrame:frame];
[iconView setIconURL:[NSURL urlWithString:@"http://original"]];
[]self.view addSubview:iconView];
使用 FlyImageCache
// 通過Key獲取單張圖片
[[FlyImageCache sharedInstance] asyncGetImageWithKey:key
completed:^(NSString *key, UIImage *image) {
imageView.image = image;
}];
// 刪除一張圖片
[[FlyImageCache sharedInstance] removeImageWithKey:key];
// 清除所有圖片
[[FlyImageCache sharedInstance] purge];
使用 FlyImageIconCache
// 添加一張小圖[[FlyImageIconCache sharedInstance] addImageWithKey:key
size:drawSize
drawingBlock:^(CGContextRef context, CGRect contextBounds) {
// 手動繪制
UIImage *image = [UIImage imageWithName:@"imageName"];
UIGraphicsPushContext(context);
[image drawInRect:contextBounds];
UIGraphicsPopContext();
}
completed:nil];
// 獲取一張小圖
[[FlyImageCache sharedInstance] asyncGetImageWithKey:key
completed:^(NSString *key, UIImage *image) {
imageView.image = image;
}];
性能
Memory
測試工程: FlyImageView / Device: iPhone6 Plus,滾動列表中連續顯示多張大圖,FlyImage不會增加Image IO的內存
Memory | FlyImage | SDWebImage | UIKit |
---|---|---|---|
All Heap Allocations | 2~7M | 2~4M | 2~5M |
All Anonymous VM | 17~30M | 310M | 17~30M |
FPS
測試工程: FlyImageIconView / Device: iPhone6 Plus,同屏渲染170張小圖,FlyImage順滑的瀏覽體驗
FlyImage | SDWebImage | UIKit |
---|---|---|
58~60FPS | 6~7FPS | 6~7FPS |
同屏多圖
類圖
-
FlyImageDataFIle封裝了 mmap 的操作,提供高效的I/O文件操作,支持讀取、寫入、動態擴張文件長度的功能。
-
FlyImageDataFileManager負責 FlyImageDataFIle 的增加、刪除和查找。使用者不能直接實例化 FlyImageDataFIle ,而是需要通過Manager進行這些操作;同時可以獲取當前文件夾下文件的數量和占用空間。
-
FlyImageDecoder解碼內存數據,并生成 UIImage 對象。 WebP 格式的轉換就在該類中完成。
-
FlyImageEncoder為 FlyImageIconCache 類服務,將圖片繪制到畫布上,生成 bitmap 格式。
-
FlyImageCache負責圖片的增加、刪除和查找。每個圖片都對應一個 key ,這些信息都會被保存在一個 meta 文件中。當該類被實例化后就會自動創建或自動獲取該 meta 文件,可以指定不同的 meta 文件路徑。在實際使用過程中,App會提供清除當前緩存的操作,但是又想將一些必要的圖片保留,比如當前用戶的頭像和未發布的草稿圖片等,針對這個需求, FlyImageCache 提供了便捷的接口 - (void)protectFileWithKey:(NSString*)key; 和 - (void)unProtectFileWithKey:(NSString*)key; 操作,處于 protect 狀態的圖片即使在執行 purge 操作時也不會被清除。
-
FlyImageIconCache負責小圖片的增加、刪除、替換和查找。和 FlyImageCache 接口基本一致,只不過該類只維護一個 FlyImageDataFIle 事例,所有小圖片解碼后都會存放在該文件中。當然你也可以創建多個實例,將經常一同使用的小圖片放在一個 FlyImageDataFIle 中。
-
FlyImageDownloader負責下載圖片,注意該類并不負責存儲。在發起一個下載請求后,會得到一個類型為 FlyImageDownloadHandlerId 的標識符,如果圖片被移出當前顯示區域后,可以調用 - (void)cancelDownloadHandler:(FlyImageDownloadHandlerId*)handlerId; 移除該下載請求,節省資源。
-
UIImageView+FlyImageCache, CALayer+FlyImageCache 為 UIImageView 提供了便捷的分類接口`。
- (void)setImageURL:(NSURL*)url;
-
UIImageView+FlyImageIconCache, CALayer+FlyImageIconCache 為 CALayer 提供了便捷的分類接口`。
- (void)setIconURL:(NSURL*)url;