看看SDWebImage源码

SDWebImage

SDWebImage 是很多iOS应用的网络图片管理第三方库,github地址:https://github.com/rs/SDWebImage 本文主要从框架到细节对SD进行剖析。

网络图片的基本流程

流程

流程

SD的流程:(以UIImageView加载方式讲述)

在UIImageView+WebCache类别中,判断是否正在进行,并使用关联添加参数,然后调用SDWebImageManager download

1
2
3
[self sd_cancelCurrentImageLoad];
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL)

在SDWebImageManager中,添加到runningOperations,查询在cache是否存在,不存在则进行SDWebImageDownloader下载,下载完成后使用

1
dispatch_main_sync_safe(^{});

返回

在SDWebImageDownloader
初始化一个operation

1
2
3
[[wself.operationClass alloc] initWithRequest:request                                           options:options                                                      progress:^(NSInteger receivedSize, NSInteger expectedSize) {}
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {}
cancelled:^{}];

再添加到downloadQueue,设置优先级,如果设置了串行,则进行

1
[wself.lastAddedOperation addDependency:operation];

依赖。
在SDWebImageDownloaderOperation中进行下载

1
2
self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO];
self.thread = [NSThread currentThread];

最后在delegate中进行回调block。

sd文件结构

NSData+ImageContentType :

根据data判断图片的格式

1
2
3
4
5
6
7
8
[data getBytes:&c length:1];

C:
1. 0xFF : jpeg
2. 0x89 : png
3. 0x47 : gif
4. 0x49 : 无
5. 0x4D : tiff
SDImageCache:

管理缓存的类(增删,是否有缓存)

有一个fileManager来管理io操作,用一个异步串行队列添加操作。

SDWebImageCompat

对image进行倍和方向操作

1
[[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
SDWebImageDecoder

图片解码

SDWebImageDownloader

图片下载类

1
2
3
4
downloadQueue 异步并行队列
lastAddedOperation 最后的操作,用于做串行下载
operationClass 操作的类,继承NSOperation
barrierQueue 异步串行操作,用于各种返回数据
1
2
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock
下载的主函数
SDWebImageDownloaderOperation

图片下载的操作

1
2
3
thread 获取下载的时候的线程,如此能在线程里取消
connection 网络连接,delegate里面获取返回值
backgroundTaskId 这个用语应用退出到后台的时候,需要调用系统一段时间运行取消下载操作
SDWebImageManager

管理一系列类的各种操作中心,想当于中转台

SDWebImageManagerDelegate

  1. 是否需要下载image
  2. 下载完成后立即变换图像
SDWebImagePrefetcher

缓存图片预取(把图片从缓存文件里面取出来到内存)

UIImage+GIF

对图片进行gif判断,如果是gif图则进行处理,返回带animationImage的图片

1
[UIImage animatedImageWithImages:images duration:duration];
UIImage+MultiFormat

图片的处理:方向

注意

最后提及 SDWebImage里面的队列有一个maxConcurrentOperationCount,默认设置为6个,那么也就最大会有同时六个线程进行下载操作,如果为1,则相当于是先入先出的概念。
这个和异步并行操作和异步串行操作有关。