iOS中的多线程一直都是比较难的一点,而SDWebImage灵活的运用了多线程来处理多个图片的下载操作,让整理的结构看起来特别的清晰,本篇就SDWebImage的功能看看它对多线程的应用
-
SDWebImage运用的queue
- dispatch_queue_t ioQueue,它在SDWebCache中,用于磁盘缓存的图片的读取,采用GCD的并发技术,因为不需要关注线程任务的中间过程,只关注图片的读取成功和失败.
_ioQueue = dispatch_queue_create("com.hackemist.SDWebImageCache", DISPATCH_QUEUE_SERIAL);
创建了一个同步的队列完成磁盘的读写操作,保证了线程的安全,获取磁盘图片存储大小,磁盘图片存储个数等需要立即返回的方法里面用了同步dispatch,其它图片读取,图片删除等通过block返回处理结果都是异步dispatch.
- NSOperationQueue *downloadQueue,它在SDWebImageDownloader中,用于下载operation的执行,因为中途可能要取消下载任务,所以使用NSOperation.
_downloadQueue = [NSOperationQueue new]; _downloadQueue.maxConcurrentOperationCount = 6; _downloadQueue.name = @"com.hackemist.SDWebImageDownloader";
将封装好的SDWebImageDownloaderOperation添加到downloadQueue中,就会在合适的时候执行对应的start方法,调用[self.dataTask resume],这样下载的请求就开始了,由于列表在快速滑动的时候,会替换下载图片的url,所以原来图片的下载任务需要取消,因此SDWebImageDownloader有个NSMutableDictionary<NSURL *,SDWebImageDownloaderOperation *> URLOperations属性,保存了添加了Operation,已备取消任务使用,而为了保证URLOperations的线程安全,使用了dispatch_semaphore_t operationsLock,在添加和删除的时候用它加锁,取消操作由最外层UIImageView上绑定的一个SDWebImageCombinedOperation对象传递而来
- dispatch_queue_t coderQueue,它在SDWebImageDownloaderOperation中,用于下载完成后的图片的解压缩操作.
_coderQueue = dispatch_queue_create("com.hackemist.SDWebImageDownloaderOperationCoderQueue", DISPATCH_QUEUE_SERIAL);
- dispatch_queue_t mutableCodersAccessQueue,它在SDWebImageCodersManager中,用于添加,删除,读取imageCode的线程安全.
_mutableCodersAccessQueue = dispatch_queue_create("com.hackemist.SDWebImageCodersManager", DISPATCH_QUEUE_CONCURRENT);
创建了同步队列,通过dispatch_barrier_sync(self.mutableCodersAccessQueue...,的方法,将mutableCodersAccessQueue前面的任务执行完后再执行自己的任务,同时在自己任务执行的时候也不允许其他任务的添加到mutableCodersAccessQueue中,保证了线程安全