SDWebImage是当下最流行的一个三方图片处理框架,我们使用较多的是它提供的UIImageView分类,支持从远程服务器下载并缓存图片。
SDWebImage框架常用方法:
- 根据图片的url下载图片并设置到ImageView上面去
/* *
* 根据图片的url下载图片并设置到ImageView上面去(进行磁盘缓存和内存缓存)
* 异步下载并缓存
*
* @param url 图片的URL
* @param placeholder 显示在UIImageView上面的占位图片,直到图片下载完成
* @param options 下载图片的选项。参考SDWebImageOptions的枚举值
* @param progressBlock 下载的进度回调
* @param completedBlock 当操作执行完毕之后的回调。该回调没有返回值
* 第一个参数为请求的图片
* 第二个参数是NSError类型的,如果图片下载成功则error为nil,否则error有值
* 第三个参数是图片缓存的使用情况(内存缓存|沙盒缓存|直接下载)
* 第四个参数是图片的URL地址
*/
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
//SDWebImageOptions的枚举值:一般使用的是SDWebImageRetryFailed | SDWebImageLowPriority
typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
SDWebImageRetryFailed = 1 << 0,//下载失败的时候会尝试重新下载(默认)
SDWebImageLowPriority = 1 << 1,//如果正在UI交互阶段会暂停下载(延迟下载)
SDWebImageCacheMemoryOnly = 1 << 2, //内存中有缓存,沙河中没有缓存
SDWebImageProgressiveDownload = 1 << 3, //如果设置的话,图片显示像浏览器显示图片一样(由上往下有进度的显示)
SDWebImageRefreshCached = 1 << 4, //将硬盘缓存交给系统自带的NSURLCache去处理
SDWebImageContinueInBackground = 1 << 5, //回到后台的时候还会继续下载
SDWebImageHandleCookies = 1 << 6, // 通过设置NSMutableURLRequest.HTTPShouldHandleCookies = YES来处理存储在NSHTTPCookieStore中的cookie
SDWebImageAllowInvalidSSLCertificates = 1 << 7,// 允许不受信任的SSL证书。主要用于测试目的。
SDWebImageHighPriority = 1 << 8, //优先下载
SDWebImageDelayPlaceholder = 1 << 9, //延迟占位符
SDWebImageTransformAnimatedImage = 1 << 10,
SDWebImageAvoidAutoSetImage = 1 << 11 //改变动画形象
};
- 下载图片调用的主方法(进行磁盘缓存和内存缓存)
/ **
* @param url 图片的URL地址
* @param options 指定此次请求策略的选项
* @param progressBlock 图片下载进度的回调
* @param completedBlock 操作完成后的回调
* 此参数是必须的,此block没有返回值
* Image:请求的 UIImage,如果出现错误,image参数是nil
* error:如果出现错误,则error有值
* cacheType:`SDImageCacheType` 枚举,标示该图像的加载方式
* SDImageCacheTypeNone:从网络下载
* SDImageCacheTypeDisk:从本地缓存加载
* SDImageCacheTypeMemory:从内存缓存加载
* finished:如果图像下载完成则为YES,如果使用 SDWebImageProgressiveDownload 选项,同时只获取到部分图片时,返回 NO
* imageURL:图片的URL地址
*
* @return SDWebImageOperation对象,应该是SDWebimageDownloaderOperation实例
*/
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url
options:(SDWebImageOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBloc
completed:(SDWebImageCompletionWithFinishedBlock)completedBlock;
- 如果我们只需要下载图片,而不需要进行cache处理的时候,我们常常用另外一个类来达成效果:
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock;
- 播放Gif图片
//传入Gif图像的名称,得到一个可动画的图像
+ (UIImage *)sd_animatedGIFNamed:(NSString *)name;
//传入Gif图像的二进制数据,得到一个可动画的图像
+ (UIImage *)sd_animatedGIFWithData:(NSData *)data;
- 内存警告处理
-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
//1.清空缓存
//clearDisk:直接删除缓存目录下面的文件,然后重新创建空的缓存文件
//cleanDisk:删除过期的文件数据,计算当前未过期的已经下载的文件数据的大小,如果发现该数据大小大于我们设置的最大缓存数据大小,那么程序内部会按照按文件数据缓存的时间从远到近删除,直到小于最大缓存数据为止。
//过期时间:7天
[[SDWebImageManager sharedManager].imageCache clearDisk];
//2.取消当前所有的操作
[[SDWebImageManager sharedManager] cancelAll];
}
SDWebImage 加载图片的原理
- 显示placeholderImage
- SDImageCache从缓存中查找图片是否已经下载
- 先从内存图片缓存查找是否有图片
- 如果内存中有图片缓存,显示图片
- 如果内存中没有,生成NSInvocationOperation添加到执行队列开始从硬盘查找图片缓存
- 如果硬盘中有,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存),显示图片
- 如果硬盘中没有,说明该图片没有缓存,需要下载图片,共享或重新生成一个下载器SDWebImageDownLoader开始下载图片
- 开始图片网络请求,下载数据
- 数据下载完成后交给SDWebImageDecoder做图片解码
- 回调展示图片
- 图片保存到硬盘缓存和内存缓存
- SDImageCache初始化会注册一些通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片(图片缓存周期是一周)
SDWebImage框架细节
-
SDWebImage内部结构
SDWebImage相关知识点补充
SDWebImage接收到内存警告的时候如何处理?采用监听系统警告通知的方式处理,接收到警告后清空缓存
SDWebImage队列最大并发数为6
SDWebImage内部设置下载图片超时时间为15m
SDWebImage图片下载操作使用了NSURLConnection类发送网络请求实现
图片的下载顺序,默认是先进先出的
SDWebImage内部如何判断图片类型?判断该图片二进制数据的第一个字节
+ (NSString *)sd_contentTypeForImageData:(NSData *)data;
-
SDWebImage做沙盒缓存时图片的命名机制是拿到图片的URL后直接对URL进行MD5加密。终端输入:echo -n "url" |MD5
SDWebImage内部使用NSCache类来进行缓存处理
NSCache是苹果官方提供的缓存类,专门用来进行缓存处理,具体使用和NSDictionary类似,在AFN和SDWebImage框架中被使用来管理缓存
苹果官方解释NSCache在系统内存很低时,会自动释放对象(但模拟器演示不会释放)建议:接收到内存警告时主动调用removeAllObject方法释放对象
NSCache是线程安全的,在多线程操作中,不需要对NSCache加锁
NSCache的Key只是对对象进行Strong引用,不是拷贝
属性介绍
@property (nullable, assign) id<NSCacheDelegate> delegate; //设置代理
@property (copy) NSString *name; //名称
@property NSUInteger totalCostLimit; //缓存空间的最大总成本,超出上限会自动回收对象。默认值为0,表示没有限制
@property NSUInteger countLimit;//能够缓存的对象的最大数量。默认值为0,表示没有限制
@property BOOL evictsObjectsWithDiscardedContent;//标识缓存是否回收废弃的内容
- 方法介绍
- (void)setObject:(ObjectType)obj forKey:(KeyType)key;//在缓存中设置指定键名对应的值,0成本
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;//在缓存中设置指定键名对应的值,并且指定该键值对的成本,用于计算记录在缓存中的所有对象的总成本,出现内存警告或者超出缓存总成本上限的时候,缓存会开启一个回收过程,删除部分元素
- (void)removeObjectForKey:(KeyType)key;//删除缓存中指定键名的对象
- (void)removeAllObjects;//删除缓存中所有的对象
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;//代理方法,即将回收对象的时候调用该方法