1、SDWebImage简单使用
先看demo中的例子,我们从例子出发解析SDWebImage.
[cell.imageView sd_setImageWithURL:[NSURLURLWithString:[_objectsobjectAtIndex:indexPath.row]]
placeholderImage:[UIImageimageNamed:@"placeholder"]options:indexPath.row ==0 ? SDWebImageRefreshCached : 0];
这个我就不多解释了,直接看这个方法的调用
@implementation UIImageView (WebCache)
...
-(void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options
...
这个方法就是为UIImageView中添加category,继续向里查看
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
1、 [selfsd_cancelCurrentImageLoad];
objc_setAssociatedObject(self, &imageURLKey, url,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
SDWebImageDelayPlaceholder图片在下载过程中的imageView将现实placeholder,表示图片下载的状态
dispatch_main_async_safe宏:如果当前是主线程就在主线程操作block 如果不是主线程就切换到主线程操作block
if (!(options &SDWebImageDelayPlaceholder)) {
dispatch_main_async_safe(^{
self.image = placeholder;
});
}
if (url) {
// check if activityView is enabled or not
是否需要显示菊花控件,如果需要就添加
if ([selfshowActivityIndicatorView]) {
[selfaddActivityIndicator];
}
__weak __typeof(self)wself =self;
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManagerdownloadImageWithURL:urloptions:options progress:progressBlockcompleted:^(UIImage *image,NSError *error, SDImageCacheType cacheType,BOOL finished,NSURL *imageURL) {
移除菊花控件
[wself removeActivityIndicator];
if (!wself) return;
dispatch_main_sync_safe(^{
if (!wself) return;
如果图片下载完成,并且状态 需要对图片进行处理(模糊、滤镜等),用SDWebImageAvoidAutoSetImage 调用这个completedBlock
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
图片下载完成对imageView设置图片
else if (image) {
wself.image = image;
刷新界面
[wself setNeedsLayout];
已经从网络获取图片但是没有成功那么加载placeholder
} else {
if ((options & SDWebImageDelayPlaceholder)) {
wself.image = placeholder;
[wself setNeedsLayout];
}
}
图片下载完成后调用的block
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
}
});
}];
封装成的opration放入到sd_setImageLoadOperation下面会有对sd_setImageLoadOperation的解释
[selfsd_setImageLoadOperation:operationforKey:@"UIImageViewImageLoad"];
} else {
dispatch_main_async_safe(^{
[selfremoveActivityIndicator];
if (completedBlock) {
NSError *error = [NSErrorerrorWithDomain:SDWebImageErrorDomaincode:-1userInfo:@{NSLocalizedDescriptionKey :@"Trying to load a nil url"}];
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
}
}
[self sd_cancelCurrentImageLoad]
******************************************
按字面意思就是取消掉当前正在下载的operation,这个方法其实就是调用的
[selfsd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"];源码
- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key {
// Cancel in progress downloader from queue
NSMutableDictionary *operationDictionary = [selfoperationDictionary];
id operations = [operationDictionary objectForKey:key];
if (operations) {
if ([operations isKindOfClass:[NSArray class]]) {
for (id <SDWebImageOperation> operationin operations) {
if (operation) {
[operation cancel];
}
}
} else if ([operationsconformsToProtocol:@protocol(SDWebImageOperation)]){
[(id<SDWebImageOperation>) operationscancel];
}
[operationDictionary removeObjectForKey:key];
}
}
先获取operation序列,就是一个字典[self operationDictionary]
- (NSMutableDictionary *)operationDictionary {
NSMutableDictionary *operations =objc_getAssociatedObject(self, &loadOperationKey);
if (operations) {
return operations;
}
operations = [NSMutableDictionary dictionary];
objc_setAssociatedObject(self, &loadOperationKey, operations,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return operations;
}
**关于objc_getAssociatedObject和objc_setAssociatedObject的使用请转我的博客
通过key值获取到的是operations数组 然后遍历所有的operation进行取消 然后将key从字典中移除
*********************************************************
sd_setImageLoadOperation
**************************************
- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key {
取消下载并移除operation同上面的一样
[selfsd_cancelImageLoadOperationWithKey:key];
获取operation字典序列
NSMutableDictionary *operationDictionary = [selfoperationDictionary];
将当前的operation添加到序列中
[operationDictionarysetObject:operationforKey:key];
}
**************************************