【无限互联】SDWebImage图片缓存流程分析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

SDWebImage是一个功能很强大的缓存网络图片的框架。

框架实现了异步加载网络图片、自动缓存图片数据等功能。

以UIImageView加载网络图片为例,对其总体的加载图片流程做一个大致的分析。

首先使用SDWebImage先要导
入#import "UIImageView+WebCache.h"文件,设置网络图片的图片地址就可以加载图片。

[objc]view plaincopy
1.NSURL *url = [NSURL URLWithString:@"/imag1e03d003
478ec54e736d196f9.jpg"];
2.[imageView setImageWithURL:url];
根据网络图片地址,SDWebImageManager类提供了方法downloadWithURL加载图片[objc]view plaincopy
1.id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downlo
adWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NS Error *error, SDImageCacheType cacheType, BOOL finished) {
2.if (!wself) return;
3. dispatch_main_sync_safe(^{
4.if (!wself) return;
5.if (image) {
6. wself.image = image;
7. [wself setNeedsLayout];
8. }
9.if (completedBlock && finished) {
10. completedBlock(image, error, cacheType);
11. }
12. });
13. }];
14. objc_setAssociatedObject(self, &operationKey, operation, OBJC_ASSOCIA
TION_RETAIN_NONATOMIC);
15. }
进入downloadWithURL方法,由SDImagerCache类提供方法queryDiskCacheForKey检查内存中是否有图片缓存,如果有图片缓存,回调block将图片数据传递给SDWebImageManger类。

SDWebImageMange 类回调block将图片数据传递给UIImageView+WebCache类去显示图片。

[objc]view plaincopy
1.UIImage *image = [self imageFromMemoryCacheForKey:key];
2.if (image) {
3. doneBlock(image, SDImageCacheTypeMemory);
4.return nil;
5. }
如果内存中没有图片缓存,将会去磁盘中查找图片缓存。

这一步操作是异步操作,如果从磁盘中读取到图片数据,将图片数据添加到内存缓存中,回调block将图片数据传递给SDWebImageManger类。

SDWebImageMange类回调block将图片数据传递给UIImageView+WebCache类去显示图片
[objc]view plaincopy
1.dispatch_async(self.ioQueue, ^{
2.if (operation.isCancelled) {
3.return;
4. }
5.
6.@autoreleasepool {
7.UIImage *diskImage = [self diskImageForKey:key];
8.if (diskImage) {
9. CGFloat cost = diskImage.size.height * diskImage.size.width
* diskImage.scale;
10. [self.memCache setObject:diskImage forKey:key cost:cost];
11. }
12.
13. dispatch_async(dispatch_get_main_queue(), ^{
14. doneBlock(diskImage, SDImageCacheTypeDisk);
15. });
16. }
内存和磁盘中都没有图片缓存,由SDWebImageDownloader类downloadImageWithURL方法请求网络下载图片。

[objc]view plaincopy
1.- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url options:(SDWeb
ImageDownloaderOptions)options progress:(void (^)(NSInteger, NSInteger))progressBlo ck completed:(void (^)(UIImage *, NSData *, NSError *, BOOL))completedBlock { 2.}
图片下载完成后,数据下载完成后交给SDWebImageDecoder做图片解码处理,图片解码完成后回调给SDWebImageDownloader类,SDWebImageDownloader类,回调block将图片数据传递给SDWebImageManger 类。

SDWebImageMange类回调block将图片数据传递给UIImageView+WebCache类显示图片。

图片数据会写入到内存和磁盘缓存中。

图片数据写入磁盘缓存中是异步操作,避免拖慢主线程。

[objc]view plaincopy
1.- (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate i
mageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk {
2.if (!image || !key) {
3.return;
4. }
5. [self.memCache setObject:image forKey:key cost:image.size.height * image
.size.width * image.scale];
6.if (toDisk) {
7. dispatch_async(self.ioQueue, ^{
8.NSData *data = imageData;
9.
10.if (image && (recalculate || !data)) {
11.BOOL imageIsPng = YES;
12.if ([imageData length] >= [kPNGSignatureData length]) {
13. imageIsPng = ImageDataHasPNGPreffix(imageData);
14. }
15.if (imageIsPng) {
16. data = UIImagePNGRepresentation(image);
17. }
18.else {
19. data = UIImageJPEGRepresentation(image, (CGFloat)1.0);
20. }
21. data = [NSBitmapImageRep representationOfImageRepsInArray:im
age.representations usingType: NSJPEGFileType properties:nil];
22. }
23.if (data) {
24.if (![_fileManager fileExistsAtPath:_diskCachePath]) {
25. [_fileManager createDirectoryAtPath:_diskCachePath withI
ntermediateDirectories:YES attributes:nil error:NULL];
26. }
27. [_fileManager createFileAtPath:[self defaultCachePathForKey:
key] contents:data attributes:nil];
28. }
29. });
30. }
31.}
总结:
1、SDWebImageManager *manager = [SDWebImageManager sharedManager];管理图片的加载,由SDImagerCache类检查内存中是否有图片缓存,或者由SDWebImageDownloader类请求网络下载图片。

2、SDImageCache 类管理图片缓存,读取图片缓存和写入图片缓存。

3、SDWebImageDownloader,根据URL向网络读取数据。

相关文档
最新文档