From 67f943b0faec54ccbe0ef446ea45f5ac0fbf17a1 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Thu, 2 Jun 2016 18:47:35 +0300 Subject: [PATCH] Implemented Lightweight Generics - both for Swift interoperability and for easier to read code --- SDWebImage/SDImageCache.m | 26 +++++++++++----------- SDWebImage/SDWebImageCompat.m | 2 +- SDWebImage/SDWebImageDownloader.h | 5 ++++- SDWebImage/SDWebImageDownloader.m | 4 ++-- SDWebImage/SDWebImageDownloaderOperation.m | 12 +++++----- SDWebImage/SDWebImageManager.m | 12 +++++----- SDWebImage/SDWebImagePrefetcher.h | 6 +++-- SDWebImage/SDWebImagePrefetcher.m | 6 ++--- SDWebImage/UIButton+WebCache.m | 6 +++-- SDWebImage/UIImageView+WebCache.h | 2 +- SDWebImage/UIImageView+WebCache.m | 8 +++---- SDWebImage/UIView+WebCacheOperation.m | 12 +++++----- 12 files changed, 56 insertions(+), 45 deletions(-) diff --git a/SDWebImage/SDImageCache.m b/SDWebImage/SDImageCache.m index cb68af28..1eea4acb 100644 --- a/SDWebImage/SDImageCache.m +++ b/SDWebImage/SDImageCache.m @@ -58,7 +58,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { @property (strong, nonatomic) NSCache *memCache; @property (strong, nonatomic) NSString *diskCachePath; -@property (strong, nonatomic) NSMutableArray *customPaths; +@property (strong, nonatomic) NSMutableArray *customPaths; @property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t ioQueue; @end @@ -190,7 +190,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { // Init the disk cache -(NSString *)makeDiskCachePath:(NSString*)fullNamespace{ - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); return [paths[0] stringByAppendingPathComponent:fullNamespace]; } @@ -345,7 +345,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { return data; } - NSArray *customPaths = [self.customPaths copy]; + NSArray *customPaths = [self.customPaths copy]; for (NSString *path in customPaths) { NSString *filePath = [self cachePathForKey:key inPath:path]; NSData *imageData = [NSData dataWithContentsOfFile:filePath]; @@ -508,7 +508,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { - (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock { dispatch_async(self.ioQueue, ^{ NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES]; - NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey]; + NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey]; // This enumerator prefetches useful properties for our cache files. NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL @@ -517,16 +517,16 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { errorHandler:NULL]; NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge]; - NSMutableDictionary *cacheFiles = [NSMutableDictionary dictionary]; + NSMutableDictionary *> *cacheFiles = [NSMutableDictionary dictionary]; NSUInteger currentCacheSize = 0; // Enumerate all of the files in the cache directory. This loop has two purposes: // // 1. Removing files that are older than the expiration date. // 2. Storing file attributes for the size-based cleanup pass. - NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init]; + NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init]; for (NSURL *fileURL in fileEnumerator) { - NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL]; + NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL]; // Skip directories. if ([resourceValues[NSURLIsDirectoryKey] boolValue]) { @@ -557,15 +557,15 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { const NSUInteger desiredCacheSize = self.maxCacheSize / 2; // Sort the remaining cache files by their last modification time (oldest first). - NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent - usingComparator:^NSComparisonResult(id obj1, id obj2) { - return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]]; - }]; + NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent + usingComparator:^NSComparisonResult(id obj1, id obj2) { + return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]]; + }]; // Delete files until we fall below our desired cache size. for (NSURL *fileURL in sortedFiles) { if ([_fileManager removeItemAtURL:fileURL error:nil]) { - NSDictionary *resourceValues = cacheFiles[fileURL]; + NSDictionary *resourceValues = cacheFiles[fileURL]; NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey]; currentCacheSize -= totalAllocatedSize.unsignedIntegerValue; @@ -609,7 +609,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath]; for (NSString *fileName in fileEnumerator) { NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName]; - NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil]; + NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil]; size += [attrs fileSize]; } }); diff --git a/SDWebImage/SDWebImageCompat.m b/SDWebImage/SDWebImageCompat.m index 958bed65..047d9509 100644 --- a/SDWebImage/SDWebImageCompat.m +++ b/SDWebImage/SDWebImageCompat.m @@ -18,7 +18,7 @@ inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) { } if ((image.images).count > 0) { - NSMutableArray *scaledImages = [NSMutableArray array]; + NSMutableArray *scaledImages = [NSMutableArray array]; for (UIImage *tempImage in image.images) { [scaledImages addObject:SDScaledImageForKey(key, tempImage)]; diff --git a/SDWebImage/SDWebImageDownloader.h b/SDWebImage/SDWebImageDownloader.h index a38d1e70..79d6bf09 100644 --- a/SDWebImage/SDWebImageDownloader.h +++ b/SDWebImage/SDWebImageDownloader.h @@ -70,7 +70,10 @@ typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteg typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage *image, NSData *data, NSError *error, BOOL finished); -typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDictionary *headers); +typedef NSDictionary SDHTTPHeadersDictionary; +typedef NSMutableDictionary SDHTTPHeadersMutableDictionary; + +typedef SDHTTPHeadersDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, SDHTTPHeadersDictionary *headers); /** * A token associated with each download. Can be used to cancel a download diff --git a/SDWebImage/SDWebImageDownloader.m b/SDWebImage/SDWebImageDownloader.m index 70b2d51d..ca0feaf1 100644 --- a/SDWebImage/SDWebImageDownloader.m +++ b/SDWebImage/SDWebImageDownloader.m @@ -19,8 +19,8 @@ @property (strong, nonatomic) NSOperationQueue *downloadQueue; @property (weak, nonatomic) NSOperation *lastAddedOperation; @property (assign, nonatomic) Class operationClass; -@property (strong, nonatomic) NSMutableDictionary *URLOperations; -@property (strong, nonatomic) NSMutableDictionary *HTTPHeaders; +@property (strong, nonatomic) NSMutableDictionary *URLOperations; +@property (strong, nonatomic) SDHTTPHeadersMutableDictionary *HTTPHeaders; // This queue is used to serialize the handling of the network responses of all the download operation in a single queue @property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t barrierQueue; diff --git a/SDWebImage/SDWebImageDownloaderOperation.m b/SDWebImage/SDWebImageDownloaderOperation.m index eb40c72d..35200f10 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.m +++ b/SDWebImage/SDWebImageDownloaderOperation.m @@ -20,9 +20,11 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis static NSString *const kProgressCallbackKey = @"progress"; static NSString *const kCompletedCallbackKey = @"completed"; +typedef NSMutableDictionary SDCallbacksDictionary; + @interface SDWebImageDownloaderOperation () -@property (strong, nonatomic) NSMutableArray *callbackBlocks; +@property (strong, nonatomic) NSMutableArray *callbackBlocks; @property (assign, nonatomic, getter = isExecuting) BOOL executing; @property (assign, nonatomic, getter = isFinished) BOOL finished; @@ -82,7 +84,7 @@ static NSString *const kCompletedCallbackKey = @"completed"; - (id)addHandlersForProgress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock { - NSMutableDictionary *callbacks = [NSMutableDictionary new]; + SDCallbacksDictionary *callbacks = [NSMutableDictionary new]; if (progressBlock) callbacks[kProgressCallbackKey] = [progressBlock copy]; if (completedBlock) callbacks[kCompletedCallbackKey] = [completedBlock copy]; dispatch_barrier_async(self.barrierQueue, ^{ @@ -91,8 +93,8 @@ static NSString *const kCompletedCallbackKey = @"completed"; return callbacks; } -- (NSArray *)callbacksForKey:(NSString *)key { - __block NSMutableArray *callbacks = nil; +- (NSArray *)callbacksForKey:(NSString *)key { + __block NSMutableArray *callbacks = nil; dispatch_sync(self.barrierQueue, ^{ // We need to remove [NSNull null] because there might not always be a progress block for each callback callbacks = [[self.callbackBlocks valueForKey:key] mutableCopy]; @@ -410,7 +412,7 @@ didReceiveResponse:(NSURLResponse *)response #pragma mark NSURLSessionTaskDelegate - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { - NSArray *completionBlocks = [[self callbacksForKey:kCompletedCallbackKey] copy]; + NSArray *completionBlocks = [[self callbacksForKey:kCompletedCallbackKey] copy]; @synchronized(self) { self.thread = nil; self.dataTask = nil; diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index 7d9ac37a..b98be34f 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -21,8 +21,8 @@ @property (strong, nonatomic, readwrite) SDImageCache *imageCache; @property (strong, nonatomic, readwrite) SDWebImageDownloader *imageDownloader; -@property (strong, nonatomic) NSMutableSet *failedURLs; -@property (strong, nonatomic) NSMutableArray *runningOperations; +@property (strong, nonatomic) NSMutableSet *failedURLs; +@property (strong, nonatomic) NSMutableArray *runningOperations; @end @@ -119,9 +119,9 @@ } - (id )loadImageWithURL:(NSURL *)url - options:(SDWebImageOptions)options - progress:(SDWebImageDownloaderProgressBlock)progressBlock - completed:(SDWebImageCompletionWithFinishedBlock)completedBlock { + options:(SDWebImageOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageCompletionWithFinishedBlock)completedBlock { // Invoking this method without a completedBlock is pointless NSAssert(completedBlock != nil, @"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead"); @@ -313,7 +313,7 @@ - (void)cancelAll { @synchronized (self.runningOperations) { - NSArray *copiedOperations = [self.runningOperations copy]; + NSArray *copiedOperations = [self.runningOperations copy]; [copiedOperations makeObjectsPerformSelector:@selector(cancel)]; [self.runningOperations removeObjectsInArray:copiedOperations]; } diff --git a/SDWebImage/SDWebImagePrefetcher.h b/SDWebImage/SDWebImagePrefetcher.h index 52e74c0f..01046da6 100644 --- a/SDWebImage/SDWebImagePrefetcher.h +++ b/SDWebImage/SDWebImagePrefetcher.h @@ -82,7 +82,7 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, * * @param urls list of URLs to prefetch */ -- (void)prefetchURLs:(NSArray *)urls; +- (void)prefetchURLs:(NSArray *)urls; /** * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, @@ -97,7 +97,9 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, * first param is the number of completed (successful or not) requests, * second parameter is the number of skipped requests */ -- (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock; +- (void)prefetchURLs:(NSArray *)urls + progress:(SDWebImagePrefetcherProgressBlock)progressBlock + completed:(SDWebImagePrefetcherCompletionBlock)completionBlock; /** * Remove and cancel queued list diff --git a/SDWebImage/SDWebImagePrefetcher.m b/SDWebImage/SDWebImagePrefetcher.m index 1dfddafd..b2809989 100644 --- a/SDWebImage/SDWebImagePrefetcher.m +++ b/SDWebImage/SDWebImagePrefetcher.m @@ -11,7 +11,7 @@ @interface SDWebImagePrefetcher () @property (strong, nonatomic) SDWebImageManager *manager; -@property (strong, nonatomic) NSArray *prefetchURLs; +@property (strong, nonatomic) NSArray *prefetchURLs; @property (assign, nonatomic) NSUInteger requestedCount; @property (assign, nonatomic) NSUInteger skippedCount; @property (assign, nonatomic) NSUInteger finishedCount; @@ -105,11 +105,11 @@ } } -- (void)prefetchURLs:(NSArray *)urls { +- (void)prefetchURLs:(NSArray *)urls { [self prefetchURLs:urls progress:nil completed:nil]; } -- (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock { +- (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock { [self cancelPrefetching]; // Prevent duplicate prefetch request self.startedTime = CFAbsoluteTimeGetCurrent(); self.prefetchURLs = urls; diff --git a/SDWebImage/UIButton+WebCache.m b/SDWebImage/UIButton+WebCache.m index fd296506..781405fa 100644 --- a/SDWebImage/UIButton+WebCache.m +++ b/SDWebImage/UIButton+WebCache.m @@ -12,6 +12,8 @@ static char imageURLStorageKey; +typedef NSMutableDictionary SDStateImageURLDictionary; + @implementation UIButton (WebCache) - (NSURL *)sd_currentImageURL { @@ -162,8 +164,8 @@ static char imageURLStorageKey; [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]]; } -- (NSMutableDictionary *)imageURLStorage { - NSMutableDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey); +- (SDStateImageURLDictionary *)imageURLStorage { + SDStateImageURLDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey); if (!storage) { storage = [NSMutableDictionary dictionary]; diff --git a/SDWebImage/UIImageView+WebCache.h b/SDWebImage/UIImageView+WebCache.h index b057aa7f..11311a3c 100644 --- a/SDWebImage/UIImageView+WebCache.h +++ b/SDWebImage/UIImageView+WebCache.h @@ -167,7 +167,7 @@ * * @param arrayOfURLs An array of NSURL */ -- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs; +- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs; /** * Cancel the current download diff --git a/SDWebImage/UIImageView+WebCache.m b/SDWebImage/UIImageView+WebCache.m index a86e4c06..190deb71 100644 --- a/SDWebImage/UIImageView+WebCache.m +++ b/SDWebImage/UIImageView+WebCache.m @@ -106,11 +106,11 @@ static char TAG_ACTIVITY_SHOW; return objc_getAssociatedObject(self, &imageURLKey); } -- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs { +- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs { [self sd_cancelCurrentAnimationImagesLoad]; __weak __typeof(self)wself = self; - NSMutableArray *operationsArray = [[NSMutableArray alloc] init]; + NSMutableArray> *operationsArray = [[NSMutableArray alloc] init]; for (NSURL *logoImageURL in arrayOfURLs) { id operation = [SDWebImageManager.sharedManager loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { @@ -119,7 +119,7 @@ static char TAG_ACTIVITY_SHOW; __strong UIImageView *sself = wself; [sself stopAnimating]; if (sself && image) { - NSMutableArray *currentImages = [[sself animationImages] mutableCopy]; + NSMutableArray *currentImages = [[sself animationImages] mutableCopy]; if (!currentImages) { currentImages = [[NSMutableArray alloc] init]; } @@ -134,7 +134,7 @@ static char TAG_ACTIVITY_SHOW; [operationsArray addObject:operation]; } - [self sd_setImageLoadOperation:[NSArray arrayWithArray:operationsArray] forKey:@"UIImageViewAnimationImages"]; + [self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"]; } - (void)sd_cancelCurrentImageLoad { diff --git a/SDWebImage/UIView+WebCacheOperation.m b/SDWebImage/UIView+WebCacheOperation.m index 1f391cda..033da216 100644 --- a/SDWebImage/UIView+WebCacheOperation.m +++ b/SDWebImage/UIView+WebCacheOperation.m @@ -11,10 +11,12 @@ static char loadOperationKey; +typedef NSMutableDictionary SDOperationsDictionary; + @implementation UIView (WebCacheOperation) -- (NSMutableDictionary *)operationDictionary { - NSMutableDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey); +- (SDOperationsDictionary *)operationDictionary { + SDOperationsDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey); if (operations) { return operations; } @@ -25,13 +27,13 @@ static char loadOperationKey; - (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key { [self sd_cancelImageLoadOperationWithKey:key]; - NSMutableDictionary *operationDictionary = [self operationDictionary]; + SDOperationsDictionary *operationDictionary = [self operationDictionary]; operationDictionary[key] = operation; } - (void)sd_cancelImageLoadOperationWithKey:(NSString *)key { // Cancel in progress downloader from queue - NSMutableDictionary *operationDictionary = [self operationDictionary]; + SDOperationsDictionary *operationDictionary = [self operationDictionary]; id operations = operationDictionary[key]; if (operations) { if ([operations isKindOfClass:[NSArray class]]) { @@ -48,7 +50,7 @@ static char loadOperationKey; } - (void)sd_removeImageLoadOperationWithKey:(NSString *)key { - NSMutableDictionary *operationDictionary = [self operationDictionary]; + SDOperationsDictionary *operationDictionary = [self operationDictionary]; [operationDictionary removeObjectForKey:key]; }