123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- #import "SDWebImagePrefetcher.h"
- @interface SDWebImagePrefetcher ()
- @property (strong, nonatomic, nonnull) SDWebImageManager *manager;
- @property (strong, nonatomic, nullable) NSArray<NSURL *> *prefetchURLs;
- @property (assign, nonatomic) NSUInteger requestedCount;
- @property (assign, nonatomic) NSUInteger skippedCount;
- @property (assign, nonatomic) NSUInteger finishedCount;
- @property (assign, nonatomic) NSTimeInterval startedTime;
- @property (copy, nonatomic, nullable) SDWebImagePrefetcherCompletionBlock completionBlock;
- @property (copy, nonatomic, nullable) SDWebImagePrefetcherProgressBlock progressBlock;
- @end
- @implementation SDWebImagePrefetcher
- + (nonnull instancetype)sharedImagePrefetcher {
- static dispatch_once_t once;
- static id instance;
- dispatch_once(&once, ^{
- instance = [self new];
- });
- return instance;
- }
- - (nonnull instancetype)init {
- return [self initWithImageManager:[SDWebImageManager new]];
- }
- - (nonnull instancetype)initWithImageManager:(SDWebImageManager *)manager {
- if ((self = [super init])) {
- _manager = manager;
- _options = SDWebImageLowPriority;
- _prefetcherQueue = dispatch_get_main_queue();
- self.maxConcurrentDownloads = 3;
- }
- return self;
- }
- - (void)setMaxConcurrentDownloads:(NSUInteger)maxConcurrentDownloads {
- self.manager.imageDownloader.maxConcurrentDownloads = maxConcurrentDownloads;
- }
- - (NSUInteger)maxConcurrentDownloads {
- return self.manager.imageDownloader.maxConcurrentDownloads;
- }
- - (void)startPrefetchingAtIndex:(NSUInteger)index {
- if (index >= self.prefetchURLs.count) return;
- self.requestedCount++;
- [self.manager loadImageWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
- if (!finished) return;
- self.finishedCount++;
- if (image) {
- if (self.progressBlock) {
- self.progressBlock(self.finishedCount,(self.prefetchURLs).count);
- }
- }
- else {
- if (self.progressBlock) {
- self.progressBlock(self.finishedCount,(self.prefetchURLs).count);
- }
-
- self.skippedCount++;
- }
- if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didPrefetchURL:finishedCount:totalCount:)]) {
- [self.delegate imagePrefetcher:self
- didPrefetchURL:self.prefetchURLs[index]
- finishedCount:self.finishedCount
- totalCount:self.prefetchURLs.count
- ];
- }
- if (self.prefetchURLs.count > self.requestedCount) {
- dispatch_async(self.prefetcherQueue, ^{
- [self startPrefetchingAtIndex:self.requestedCount];
- });
- } else if (self.finishedCount == self.requestedCount) {
- [self reportStatus];
- if (self.completionBlock) {
- self.completionBlock(self.finishedCount, self.skippedCount);
- self.completionBlock = nil;
- }
- self.progressBlock = nil;
- }
- }];
- }
- - (void)reportStatus {
- NSUInteger total = (self.prefetchURLs).count;
- if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)]) {
- [self.delegate imagePrefetcher:self
- didFinishWithTotalCount:(total - self.skippedCount)
- skippedCount:self.skippedCount
- ];
- }
- }
- - (void)prefetchURLs:(nullable NSArray<NSURL *> *)urls {
- [self prefetchURLs:urls progress:nil completed:nil];
- }
- - (void)prefetchURLs:(nullable NSArray<NSURL *> *)urls
- progress:(nullable SDWebImagePrefetcherProgressBlock)progressBlock
- completed:(nullable SDWebImagePrefetcherCompletionBlock)completionBlock {
- [self cancelPrefetching];
- self.startedTime = CFAbsoluteTimeGetCurrent();
- self.prefetchURLs = urls;
- self.completionBlock = completionBlock;
- self.progressBlock = progressBlock;
- if (urls.count == 0) {
- if (completionBlock) {
- completionBlock(0,0);
- }
- } else {
-
- NSUInteger listCount = self.prefetchURLs.count;
- for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) {
- [self startPrefetchingAtIndex:i];
- }
- }
- }
- - (void)cancelPrefetching {
- self.prefetchURLs = nil;
- self.skippedCount = 0;
- self.requestedCount = 0;
- self.finishedCount = 0;
- [self.manager cancelAll];
- }
- @end
|