SDWebImage是iOS開發常用的一個開源庫,主要作用是異步下載圖片并顯示在UIImageView上。具體功能有:
1.異步加載圖片;
2.異步緩存圖片在內存和磁盤;
3.支持GIF、WebP圖片
4.支持后臺圖片解壓縮;
5.同一個URL不會被反復下載;
6.同一個非法的URL不會被反復加載;
7.線程安全, 不會阻塞主線程。
主要流程:
Paste_Image.png
UIImageView+WebCache
我們最常用到的接口應該是這幾個:
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
不過最后都是調用到下面這個接口,
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
// 取消之前的下載操作
[self sd_cancelCurrentImageLoad];
// 動態關聯url,唯一key
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if (!(options & SDWebImageDelayPlaceholder)) {
// 將任務放在主線程
dispatch_main_async_safe(^{
// 展位圖
self.image = placeholder;
});
}
if (url) {
// 是否顯示進度
// check if activityView is enabled or not
if ([self showActivityIndicatorView]) {
[self addActivityIndicator];
}
__weak __typeof(self)wself = self;
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
[wself removeActivityIndicator];
if (!wself) return;
dispatch_main_sync_safe(^{
if (!wself) return;
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
else if (image) {
wself.image = image;
// 重新布局
[wself setNeedsLayout];
} else {
if ((options & SDWebImageDelayPlaceholder)) {
wself.image = placeholder;
[wself setNeedsLayout];
}
}
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
}
});
}];
// 前面把UIImageView的下載操作取消了,重新為UIImageView綁定新的操作
[self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
} else {
dispatch_main_async_safe(^{
[self removeActivityIndicator];
// 出錯處理
if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
}
}
SDWebImageOptions
typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
/**
下載失敗會重新嘗試下載
*/
SDWebImageRetryFailed = 1 << 0,
/**
UIScrollView滾動時,延遲下載
*/
SDWebImageLowPriority = 1 << 1,
/**
只緩存到內存中
*/
SDWebImageCacheMemoryOnly = 1 << 2,
/**
圖片變下載變顯示,默認的是下載完成再顯示
*/
SDWebImageProgressiveDownload = 1 << 3,
/**
刷新緩存
*/
SDWebImageRefreshCached = 1 << 4,
/**
后臺下載
*/
SDWebImageContinueInBackground = 1 << 5,
SDWebImageHandleCookies = 1 << 6,
SDWebImageAllowInvalidSSLCertificates = 1 << 7,
SDWebImageHighPriority = 1 << 8,
SDWebImageDelayPlaceholder = 1 << 9,
SDWebImageTransformAnimatedImage = 1 << 10,
SDWebImageAvoidAutoSetImage = 1 << 11
}
SDWebImageDownloaderProgressBlock 進度block。
SDWebImageCompletionBlock 結束block。