iOS 图片加载框架SDWebImage解读
目的
在使用SDWebImage加载图片时,尤其是加载gif等大图时,SDWebImage会将图片缓存在内存中,这样是非常吃内存的,这时我们就需要在适当的时候去释放一下SDWebImage的内存缓存,才不至于造成APP闪退。
SDWebImage提供了UIImageView、UIButton、MKAnnotationView的图片下载分类,只要一行代码就可以实现图片异步下载和缓存功能。
这样开发者就无须花太多精力在图片下载细节上,专心处理业务逻辑。
SDWebImage特点
- 提供UIImageView,UIButton,MKAnnotationView的分类,用来显示网络图片,以及缓存管理
- 异步下载图片
- 异步缓存(内存+磁盘),并且自动管理缓存有效性
- 后台图片解压缩
- 同一个URL不会重复下载
- 自动识别无效URL,不会反复重试
- 不阻塞主线程
- 高性能
- 使用GCD和ARC
- 支持多种图片格式(包括WebP格式)
- 支持动图(GIF)
- 4.0之前的动图效果并不是太好
- 4.0以后基于FLAnimatedImage加载动图
注:本文选读的代码是3.7.3版本的,所以动图加载还不支持FLAnimatedImage。
SDWebImage使用
1.UITableView中使用UIImageView+WebCache
[cell.imageViewsd_setImageWithURL:[NSURLURLWithString:@"http://www.domain.com/path/to/image.jpg"]placeholderImage:[UIImageimageNamed:@"placeholder.png"]];
2.使用回调blocks
在block中得到图片下载进度和图片加载完成(下载完成或者读取缓存)的回调,如果你在图片加载完成前取消了请求操作,就不会收到成功或失败的回调
[cell.imageViewsd_setImageWithURL:[NSURLURLWithString:@"http://www.domain.com/path/to/image.jpg"] placeholderImage:[UIImageimageNamed:@"placeholder.png"] completed:^(UIImage*image,NSError*error,SDImageCacheTypecacheType,NSURL*imageURL){ ...completioncodehere... }];
3.SDWebImageManager的使用
UIImageView(WebCache)分类的核心在于SDWebImageManager的下载和缓存处理,SDWebImageManager将图片下载和图片缓存组合起来了。SDWebImageManager也可以单独使用。
SDWebImageManager*manager=[SDWebImageManagersharedManager]; [managerloadImageWithURL:imageURL options:0 progress:^(NSIntegerreceivedSize,NSIntegerexpectedSize){ //progressiontrackingcode } completed:^(UIImage*image,NSError*error,SDImageCacheTypecacheType,BOOLfinished,NSURL*imageURL){ if(image){ //dosomethingwithimage } }];
4.单独使用SDWebImageDownloader异步下载图片
我们还可以单独使用SDWebImageDownloader来下载图片,但是图片内容不会缓存。
SDWebImageDownloader*downloader=[SDWebImageDownloadersharedDownloader]; [downloaderdownloadImageWithURL:imageURL options:0 progress:^(NSIntegerreceivedSize,NSIntegerexpectedSize){ //progressiontrackingcode } completed:^(UIImage*image,NSData*data,NSError*error,BOOLfinished){ if(image&&finished){ //dosomethingwithimage } }];
5.单独使用SDImageCache异步缓存图片
SDImageCache支持内存缓存和异步的磁盘缓存(可选),如果你想单独使用SDImageCache来缓存数据的话,可以使用单例,也可以创建一个有独立命名空间的SDImageCache实例。
添加缓存的方法:
[[SDImageCachesharedImageCache]storeImage:myImageforKey:myCacheKey];
默认情况下,图片数据会同时缓存到内存和磁盘中,如果你想只要内存缓存的话,可以使用下面的方法:
[[SDImageCachesharedImageCache]storeImage:myImageforKey:myCacheKeytoDisk:NO];
读取缓存时可以使用queryDiskCacheForKey:done:方法,图片缓存的key是唯一的,通常就是图片的absoluteURL。
SDImageCache*imageCache=[[SDImageCachealloc]initWithNamespace:@"myNamespace"]; [imageCachequeryDiskCacheForKey:myCacheKeydone:^(UIImage*image){ //imageisnotnilifimagewasfound }];
6.自定义缓存key
有时候,一张图片的URL中的一部分可能是动态变化的(比如获取权限上的限制),所以我们只需要把URL中不变的部分作为缓存用的key。
SDWebImageManager.sharedManager.cacheKeyFilter=^(NSURL*url){ url=[[NSURLalloc]initWithScheme:url.schemehost:url.hostpath:url.path]; return[urlabsoluteString]; };
常见问题
问题1:使用UITableViewCell中的imageView加载不同尺寸的网络图片时会出现尺寸缩放问题。
解决方案:
自定义UITableViewCell,重写-layoutSubviews方法,调整位置尺寸;
或者直接弃用UITableViewCell的imageView,自己添加一个imageView作为子控件。
问题2:图片刷新问题:SDWebImage在进行缓存时忽略了所有服务器返回的cachingcontrol设置,并且在缓存时没有做时间限制,这也就意味着图片URL必须是静态的了,要求服务器上一个URL对应的图片内容不允许更新。但是如果存储图片的服务器不由自己控制,也就是说图片内容更新了,URL却没有更新,这种情况怎么办?
解决方案:在调用sd_setImageWithURL:placeholderImage:options:方法时设置options参数为SDWebImageRefreshCached,这样虽然会降低性能,但是下载图片时会照顾到服务器返回的cachingcontrol。
问题3:在加载图片时,如何添加默认的progressindicator?
解决方案:在调用-sd_setImageWithURL:方法之前,先调用下面的方法:
[imageViewsd_setShowActivityIndicatorView:YES]; [imageViewsd_setIndicatorStyle:UIActivityIndicatorViewStyleGray]; ```![](http://upload-images.jianshu.io/upload_images/2829694-48307b4d71bc5800.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/300)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。