UIView+WebCacheOperation
个人理解此分类的作用:动态的绑定每个UIView与其持有的Operation(下载任务),即设置一个NSMutableDictionary
类型的属性,以方便管理UIView的操作。
1
- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key;
- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key;
- (void)sd_removeImageLoadOperationWithKey:(NSString *)key;
方法1. 为Dictionary属性
绑定NSOperation操作。首先是取消之前UIView正在执行的操作,先移除然后重新设置覆盖属性(保证Operation的唯一性)。
方法2. 为UIView当前的Operation取消所有的操作(imageCache缓存查找操作、下载操作)。注意的是可能UIView在执行一整组图片的下载UIImageViewAnimationImages
,即可能是Dictionary属性
中Key的值对应是数组Operations。
方法3. 移除Dictionary属性
的key值,即取消Operation操作绑定。
2
此类中,使用了Runtime运行时,动态的给分类添加属性operationDictionary
。
objc_getAssociatedObject
和objc_setAssociatedObject
类似于iOS内部的get和set方法。使用时需设置一个objc_AssociationPolicy
参数。Option键查看文档。
可知:
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
OBJC_ASSOCIATION_ASSIGN = 0, /**< Specifies a weak reference to the associated object. */
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object.
* The association is not made atomically. */
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /**< Specifies that the associated object is copied.
* The association is not made atomically. */
OBJC_ASSOCIATION_RETAIN = 01401, /**< Specifies a strong reference to the associated object.
* The association is made atomically. */
OBJC_ASSOCIATION_COPY = 01403 /**< Specifies that the associated object is copied.
* The association is made atomically. */
};
看解释,类似于给属性设置关键字property的修饰符(Strong、retain、copy、weak、assign)。
至此,该分类基本分析完。
SDWebImagePrefetcher
预处理需要下载的图片URL,为之后需要使用时候做准备,然而此预处理的优先级是较低的。
设置了maxConcurrentDownloads
最大下载并发数为3,并在默认的Main线程中进行。
- (void)startPrefetchingAtIndex:(NSUInteger)index {
// 递归
if (self.prefetchURLs.count > self.requestedCount) {
dispatch_async(self.prefetcherQueue, ^{
[self startPrefetchingAtIndex:self.requestedCount];
});
}
}
对需要预处理的URLs进行下载操作,递归进行。图片下载成功,则返回,失败则跳过。对URLs全部处理完,则重置一些状态。
实现了SDWebImagePrefetcherDelegate
代理的话,返回对URLs的处理情况。
WebCache的分类
UIButton+WebCache
、UIImageView+HighlightedWebCache
、UIImageView+WebCache
、这几个分类都是相似度很高的,主要用于View异步加载图片。
1
UIImageView+WebCache
为UIImageView动态添加一个指示器UIActivityIndicatorView
,如果需要使用时,设置是否在ImageView上显示以及指示器类型:
/**
* Show activity UIActivityIndicatorView
*/
- (void)setShowActivityIndicatorView:(BOOL)show;
/**
* set desired UIActivityIndicatorViewStyle
*
* @param style The style of the UIActivityIndicatorView
*/
- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style;
使用Runtime添加ActivityIndicatorView
指示器的写法也很清晰明了,值得我们学习。
2
来看核心方法:
- (void)sd_setImageWithURL:(NSURL *)url
placeholderImage:(UIImage *)placeholder
options:(SDWebImageOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageCompletionBlock)completedBlock
先取消UIView当前正在进行的任务(下载、缓存查询),并添加设置属性imageURLKey
。
非SDWebImageDelayPlaceholder
情况下,设置UIImageView的占位图placeholder。
生成下载任务SDWebImageOperation
,并把operation绑定到UIImageView视图。处理下载operation完成后的回调,设置UIImageView的image等。
3
到此,SDWebImage的源码基本已经阅读完毕。