Implemented Lightweight Generics - both for Swift interoperability and for easier to read code

This commit is contained in:
Bogdan Poplauschi 2016-06-02 18:47:35 +03:00 committed by Bogdan Poplauschi
parent c4dd0eee49
commit 67f943b0fa
12 changed files with 56 additions and 45 deletions

View File

@ -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<NSString *> *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<NSString *> *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<NSString *> *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<NSString *> *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<NSURL *, NSDictionary<NSString *, id> *> *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<NSURL *> *urlsToDelete = [[NSMutableArray alloc] init];
for (NSURL *fileURL in fileEnumerator) {
NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL];
NSDictionary<NSString *, id> *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<NSURL *> *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<NSString *, id> *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<NSString *, id> *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
size += [attrs fileSize];
}
});

View File

@ -18,7 +18,7 @@ inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) {
}
if ((image.images).count > 0) {
NSMutableArray *scaledImages = [NSMutableArray array];
NSMutableArray<UIImage *> *scaledImages = [NSMutableArray array];
for (UIImage *tempImage in image.images) {
[scaledImages addObject:SDScaledImageForKey(key, tempImage)];

View File

@ -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<NSString *, NSString *> SDHTTPHeadersDictionary;
typedef NSMutableDictionary<NSString *, NSString *> SDHTTPHeadersMutableDictionary;
typedef SDHTTPHeadersDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, SDHTTPHeadersDictionary *headers);
/**
* A token associated with each download. Can be used to cancel a download

View File

@ -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<NSURL *, SDWebImageDownloaderOperation *> *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;

View File

@ -20,9 +20,11 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
static NSString *const kProgressCallbackKey = @"progress";
static NSString *const kCompletedCallbackKey = @"completed";
typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
@interface SDWebImageDownloaderOperation ()
@property (strong, nonatomic) NSMutableArray *callbackBlocks;
@property (strong, nonatomic) NSMutableArray<SDCallbacksDictionary *> *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<id> *)callbacksForKey:(NSString *)key {
__block NSMutableArray<id> *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<id> *completionBlocks = [[self callbacksForKey:kCompletedCallbackKey] copy];
@synchronized(self) {
self.thread = nil;
self.dataTask = nil;

View File

@ -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<NSURL *> *failedURLs;
@property (strong, nonatomic) NSMutableArray<SDWebImageCombinedOperation *> *runningOperations;
@end
@ -119,9 +119,9 @@
}
- (id <SDWebImageOperation>)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<SDWebImageCombinedOperation *> *copiedOperations = [self.runningOperations copy];
[copiedOperations makeObjectsPerformSelector:@selector(cancel)];
[self.runningOperations removeObjectsInArray:copiedOperations];
}

View File

@ -82,7 +82,7 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls,
*
* @param urls list of URLs to prefetch
*/
- (void)prefetchURLs:(NSArray *)urls;
- (void)prefetchURLs:(NSArray<NSURL *> *)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<NSURL *> *)urls
progress:(SDWebImagePrefetcherProgressBlock)progressBlock
completed:(SDWebImagePrefetcherCompletionBlock)completionBlock;
/**
* Remove and cancel queued list

View File

@ -11,7 +11,7 @@
@interface SDWebImagePrefetcher ()
@property (strong, nonatomic) SDWebImageManager *manager;
@property (strong, nonatomic) NSArray *prefetchURLs;
@property (strong, nonatomic) NSArray<NSURL *> *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<NSURL *> *)urls {
[self prefetchURLs:urls progress:nil completed:nil];
}
- (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock {
- (void)prefetchURLs:(NSArray<NSURL *> *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock {
[self cancelPrefetching]; // Prevent duplicate prefetch request
self.startedTime = CFAbsoluteTimeGetCurrent();
self.prefetchURLs = urls;

View File

@ -12,6 +12,8 @@
static char imageURLStorageKey;
typedef NSMutableDictionary<NSNumber *, NSURL *> 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];

View File

@ -167,7 +167,7 @@
*
* @param arrayOfURLs An array of NSURL
*/
- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs;
- (void)sd_setAnimationImagesWithURLs:(NSArray<NSURL *> *)arrayOfURLs;
/**
* Cancel the current download

View File

@ -106,11 +106,11 @@ static char TAG_ACTIVITY_SHOW;
return objc_getAssociatedObject(self, &imageURLKey);
}
- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs {
- (void)sd_setAnimationImagesWithURLs:(NSArray<NSURL *> *)arrayOfURLs {
[self sd_cancelCurrentAnimationImagesLoad];
__weak __typeof(self)wself = self;
NSMutableArray *operationsArray = [[NSMutableArray alloc] init];
NSMutableArray<id<SDWebImageOperation>> *operationsArray = [[NSMutableArray alloc] init];
for (NSURL *logoImageURL in arrayOfURLs) {
id <SDWebImageOperation> 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<UIImage *> *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 {

View File

@ -11,10 +11,12 @@
static char loadOperationKey;
typedef NSMutableDictionary<NSString *, id> 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];
}