IOS 網路-深入淺出(一 )-> 三方SDWebImage,iossdwebimage
首要我們以最為常用的UIImageView為例介紹實現原理:
1)UIImageView+WebCache: setImageWithURL:placeholderImage:options: 先顯示 placeholderImage ,同時由SDWebImageManager 根據 URL 來在本地尋找圖片。
2)SDWebImageManager: downloadWithURL:delegate:options:userInfo: SDWebImageManager是將UIImageView+WebCache同SDImageCache連結起來的類, SDImageCache: queryDiskCacheForKey:delegate:userInfo:用來從緩衝根據CacheKey尋找圖片是否已經在緩衝中
3)如果記憶體中已經有圖片緩衝, SDWebImageManager會回調SDImageCacheDelegate : imageCache:didFindImage:forKey:userInfo:
4)而 UIImageView+WebCache 則回調SDWebImageManagerDelegate: webImageManager:didFinishWithImage:來顯示圖片。
5)如果記憶體中沒有圖片緩衝,那麼產生 NSInvocationOperation 添加到隊列,從硬碟尋找圖片是否已被下載快取。
6)根據 URLKey 在硬碟緩衝目錄下嘗試讀取圖片檔案。這一步是在 NSOperation 進行的操作,所以回主線程進行結果回調 notifyDelegate:。
7)如果上一操作從硬碟讀取到了圖片,將圖片添加到記憶體緩衝中(如果空閑記憶體過小,會先清空記憶體緩衝)。SDImageCacheDelegate 回調 imageCache:didFindImage:forKey:userInfo:。進而回調展示圖片。
8)如果從硬碟緩衝目錄讀取不到圖片,說明所有緩衝都不存在該圖片,需要下載圖片,回調 imageCache:didNotFindImageForKey:userInfo:。
9)共用或重建一個下載器 SDWebImageDownloader 開始下載圖片。
10)圖片下載由 NSURLConnection 來做,實現相關 delegate 來判斷圖片下載中、下載完成和下載失敗。
11)connection:didReceiveData: 中利用 ImageIO 做了按圖片下載進度載入效果。
12)connectionDidFinishLoading: 資料下載完成後交給 SDWebImageDecoder 做圖片解碼處理。
13)圖片解碼處理在一個 NSOperationQueue 完成,不會拖慢主線程 UI。如果有需要對下載的圖片進行二次處理,最好也在這裡完成,效率會好很多。
14)在主線程 notifyDelegateOnMainThreadWithInfo: 宣告解碼完成,imageDecoder:didFinishDecodingImage:userInfo: 回調給 SDWebImageDownloader。
15)imageDownloader:didFinishWithImage: 回調給 SDWebImageManager 告知圖片下載完成。
16)通知所有的 downloadDelegates 下載完成,回調給需要的地方展示圖片。
17)將圖片儲存到 SDImageCache 中,記憶體緩衝和硬碟緩衝同時儲存。
18)寫檔案到硬碟在單獨 NSInvocationOperation 中完成,避免拖慢主線程。
19) 如果是在iOS上運行,SDImageCache 在初始化的時候會註冊notification 到 UIApplicationDidReceiveMemoryWarningNotification 以及 UIApplicationWillTerminateNotification,在記憶體警告的時候清理記憶體配置圖片緩衝,應用結束的時候清理到期圖片。
20)SDWebImagePrefetcher 可以預先下載圖片,方便後續使用。
*以上為轉載*
*以下為原創*
SDWebImage主要是用於網狀圖片的擷取。
當然也可用於其他動作。
例如對button的操作,不過都是大同小異。
因此在這裡不過多嘮叨。
重點是理解SDWebImage是如何?,並且該如何使用。
//// ViewController.m// CX-深入淺出 SDWebImage//// Created by ma c on 16/3/24.// Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import "ViewController.h"#import "UIImageView+WebCache.h"//由於網路問題這裡使用的是本機伺服器static NSString * urlString = @"http://localhost/nvshen.jpeg";@interface ViewController ()@property (weak, nonatomic) IBOutlet UIImageView *imageVIew;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad];}- (IBAction)downLoad:(id)sender { /* options所有選項: //失敗後重試 (經常使用) SDWebImageRetryFailed = 1 << 0, //UI互動期間開始下載,導致延遲下載比如UIScrollView減速。(經常使用) SDWebImageLowPriority = 1 << 1, //只進行記憶體緩衝 SDWebImageCacheMemoryOnly = 1 << 2, //這個標誌可以漸進式下載,顯示的映像是逐步在下載 SDWebImageProgressiveDownload = 1 << 3, //重新整理緩衝 SDWebImageRefreshCached = 1 << 4, //後台下載 SDWebImageContinueInBackground = 1 << 5, //優先下載 SDWebImageHighPriority = 1 << 8, //延遲預留位置 SDWebImageDelayPlaceholder = 1 << 9, //改變動畫形象 SDWebImageTransformAnimatedImage = 1 << 10, */ /* 只是擷取圖片 1)self.imageVIew sd_setImageWithURL:[NSURL URLWithString:urlString] 擷取圖片 完成後可操作 2)[self.imageVIew sd_setImageWithURL:[NSURL URLWithString:urlString] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { }]; 擷取動畫(圖片組) 3)self.imageVIew sd_setAnimationImagesWithURLs:<#(NSArray *)#> 從之前緩衝裡擷取 4)self.imageVIew sd_setImageWithPreviousCachedImageWithURL:<#(NSURL *)#> placeholderImage:<#(UIImage *)#> options:<#(SDWebImageOptions)#> progress:<#^(NSInteger receivedSize, NSInteger expectedSize)progressBlock#> completed:<#^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)completedBlock#> */ //較完整的操作 /* URl:這裡是網路地址 placeholderImage:佔為圖片,在下載完成前顯示 options:操作選項 completed:完成後-> */ [self.imageVIew sd_setImageWithPreviousCachedImageWithURL:[NSURL URLWithString:urlString] placeholderImage:nil options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) { //這裡是下載進度 //receivedSize 已經下載的大小 //expectedSize 總大小 } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { //下載完成後 //可以是成功,也可以是失敗。 }]; }@end
有時候我們需要測試圖片是否真正存入到沙箱內,因此我們需要擷取到沙箱的地址。
方法如下
NSString * path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSLog(@"%@",path);
擷取地址後我們可以在終端開啟
️GIF️