SDWebImage是iOS开发常用的一个开源库,主要作用是异步下载图片并显示在UIImageView上。具体功能有:
1.异步加载图片;
2.异步缓存图片在内存和磁盘;
3.支持GIF、WebP图片
4.支持后台图片解压缩;
5.同一个URL不会被反复下载;
6.同一个非法的URL不会被反复加载;
7.线程安全, 不会阻塞主线程。
主要流程:
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。