Skip to content

Commit 710908e

Browse files
author
Olivier Poitrey
committed
Merge pull request SDWebImage#676 from matej/cache-gcd-fixes
Various GCD related fixes for SDImageCache
2 parents 4b26a89 + 556665d commit 710908e

File tree

2 files changed

+64
-47
lines changed

2 files changed

+64
-47
lines changed

SDWebImage/SDImageCache.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType ca
128128
- (void)removeImageForKey:(NSString *)key;
129129

130130
/**
131-
* Remove the image from memory and optionaly disk cache synchronously
131+
* Remove the image from memory and optionally disk cache synchronously
132132
*
133133
* @param key The unique image cache key
134134
* @param fromDisk Also remove cache entry from disk if YES
@@ -140,14 +140,27 @@ typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType ca
140140
*/
141141
- (void)clearMemory;
142142

143+
/**
144+
* Clear all disk cached images. Non-blocking method - returns immediately.
145+
* @param completionBlock An block that should be executed after cache expiration completes (optional)
146+
*/
147+
- (void)clearDiskOnCompletion:(void (^)())completion;
148+
143149
/**
144150
* Clear all disk cached images
151+
* @see clearDiskOnCompletion:
145152
*/
146153
- (void)clearDisk;
147-
- (void)clearDiskOnCompletion:(void (^)())completion;
154+
155+
/**
156+
* Remove all expired cached image from disk. Non-blocking method - returns immediately.
157+
* @param completionBlock An block that should be executed after cache expiration completes (optional)
158+
*/
159+
- (void)cleanDiskWithCompletionBlock:(void (^)())completionBlock;
148160

149161
/**
150162
* Remove all expired cached image from disk
163+
* @see cleanDiskWithCompletionBlock:
151164
*/
152165
- (void)cleanDisk;
153166

SDWebImage/SDImageCache.m

Lines changed: 49 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,11 @@ - (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate image
181181
}
182182

183183
if (data) {
184-
// Can't use defaultManager another thread
185-
NSFileManager *fileManager = [NSFileManager new];
186-
187-
if (![fileManager fileExistsAtPath:_diskCachePath]) {
188-
[fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL];
184+
if (![_fileManager fileExistsAtPath:_diskCachePath]) {
185+
[_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL];
189186
}
190187

191-
[fileManager createFileAtPath:[self defaultCachePathForKey:key] contents:data attributes:nil];
188+
[_fileManager createFileAtPath:[self defaultCachePathForKey:key] contents:data attributes:nil];
192189
}
193190
});
194191
}
@@ -296,7 +293,7 @@ - (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(void (^)(UIImage *im
296293
[self.memCache setObject:diskImage forKey:key cost:cost];
297294
}
298295

299-
dispatch_main_sync_safe(^{
296+
dispatch_async(dispatch_get_main_queue(), ^{
300297
doneBlock(diskImage, SDImageCacheTypeDisk);
301298
});
302299
}
@@ -318,7 +315,7 @@ - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk {
318315

319316
if (fromDisk) {
320317
dispatch_async(self.ioQueue, ^{
321-
[[NSFileManager defaultManager] removeItemAtPath:[self defaultCachePathForKey:key] error:nil];
318+
[_fileManager removeItemAtPath:[self defaultCachePathForKey:key] error:nil];
322319
});
323320
}
324321
}
@@ -342,31 +339,34 @@ - (void)clearDisk {
342339
- (void)clearDiskOnCompletion:(void (^)())completion
343340
{
344341
dispatch_async(self.ioQueue, ^{
345-
[[NSFileManager defaultManager] removeItemAtPath:self.diskCachePath error:nil];
346-
[[NSFileManager defaultManager] createDirectoryAtPath:self.diskCachePath
347-
withIntermediateDirectories:YES
348-
attributes:nil
349-
error:NULL];
342+
[_fileManager removeItemAtPath:self.diskCachePath error:nil];
343+
[_fileManager createDirectoryAtPath:self.diskCachePath
344+
withIntermediateDirectories:YES
345+
attributes:nil
346+
error:NULL];
350347

351348
if (completion) {
352-
dispatch_main_sync_safe(^{
349+
dispatch_async(dispatch_get_main_queue(), ^{
353350
completion();
354351
});
355352
}
356353
});
357354
}
358355

359356
- (void)cleanDisk {
357+
[self cleanDiskWithCompletionBlock:nil];
358+
}
359+
360+
- (void)cleanDiskWithCompletionBlock:(void (^)())completionBlock {
360361
dispatch_async(self.ioQueue, ^{
361-
NSFileManager *fileManager = [NSFileManager defaultManager];
362362
NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];
363363
NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey];
364364

365365
// This enumerator prefetches useful properties for our cache files.
366-
NSDirectoryEnumerator *fileEnumerator = [fileManager enumeratorAtURL:diskCacheURL
367-
includingPropertiesForKeys:resourceKeys
368-
options:NSDirectoryEnumerationSkipsHiddenFiles
369-
errorHandler:NULL];
366+
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL
367+
includingPropertiesForKeys:resourceKeys
368+
options:NSDirectoryEnumerationSkipsHiddenFiles
369+
errorHandler:NULL];
370370

371371
NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge];
372372
NSMutableDictionary *cacheFiles = [NSMutableDictionary dictionary];
@@ -387,7 +387,7 @@ - (void)cleanDisk {
387387
// Remove files that are older than the expiration date;
388388
NSDate *modificationDate = resourceValues[NSURLContentModificationDateKey];
389389
if ([[modificationDate laterDate:expirationDate] isEqualToDate:expirationDate]) {
390-
[fileManager removeItemAtURL:fileURL error:nil];
390+
[_fileManager removeItemAtURL:fileURL error:nil];
391391
continue;
392392
}
393393

@@ -411,7 +411,7 @@ - (void)cleanDisk {
411411

412412
// Delete files until we fall below our desired cache size.
413413
for (NSURL *fileURL in sortedFiles) {
414-
if ([fileManager removeItemAtURL:fileURL error:nil]) {
414+
if ([_fileManager removeItemAtURL:fileURL error:nil]) {
415415
NSDictionary *resourceValues = cacheFiles[fileURL];
416416
NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];
417417
currentCacheSize -= [totalAllocatedSize unsignedIntegerValue];
@@ -422,6 +422,11 @@ - (void)cleanDisk {
422422
}
423423
}
424424
}
425+
if (completionBlock) {
426+
dispatch_async(dispatch_get_main_queue(), ^{
427+
completionBlock();
428+
});
429+
}
425430
});
426431
}
427432

@@ -435,33 +440,33 @@ - (void)backgroundCleanDisk {
435440
}];
436441

437442
// Start the long-running task and return immediately.
438-
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
439-
// Do the work associated with the task, preferably in chunks.
440-
[self cleanDisk];
441-
443+
[self cleanDiskWithCompletionBlock:^{
442444
[application endBackgroundTask:bgTask];
443445
bgTask = UIBackgroundTaskInvalid;
444-
});
446+
}];
445447
}
446448

447449
- (NSUInteger)getSize {
448-
NSUInteger size = 0;
449-
NSDirectoryEnumerator *fileEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:self.diskCachePath];
450-
for (NSString *fileName in fileEnumerator) {
451-
NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName];
452-
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
453-
size += [attrs fileSize];
454-
}
450+
__block NSUInteger size = 0;
451+
dispatch_sync(self.ioQueue, ^{
452+
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
453+
for (NSString *fileName in fileEnumerator) {
454+
NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName];
455+
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
456+
size += [attrs fileSize];
457+
}
458+
});
455459
return size;
456460
}
457461

458462
- (int)getDiskCount {
459-
int count = 0;
460-
NSDirectoryEnumerator *fileEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:self.diskCachePath];
461-
for (__unused NSString *fileName in fileEnumerator) {
462-
count += 1;
463-
}
464-
463+
__block int count = 0;
464+
dispatch_sync(self.ioQueue, ^{
465+
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
466+
for (__unused NSString *fileName in fileEnumerator) {
467+
count += 1;
468+
}
469+
});
465470
return count;
466471
}
467472

@@ -472,11 +477,10 @@ - (void)calculateSizeWithCompletionBlock:(void (^)(NSUInteger fileCount, NSUInte
472477
NSUInteger fileCount = 0;
473478
NSUInteger totalSize = 0;
474479

475-
NSFileManager *fileManager = [NSFileManager defaultManager];
476-
NSDirectoryEnumerator *fileEnumerator = [fileManager enumeratorAtURL:diskCacheURL
477-
includingPropertiesForKeys:@[NSFileSize]
478-
options:NSDirectoryEnumerationSkipsHiddenFiles
479-
errorHandler:NULL];
480+
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL
481+
includingPropertiesForKeys:@[NSFileSize]
482+
options:NSDirectoryEnumerationSkipsHiddenFiles
483+
errorHandler:NULL];
480484

481485
for (NSURL *fileURL in fileEnumerator) {
482486
NSNumber *fileSize;
@@ -486,7 +490,7 @@ - (void)calculateSizeWithCompletionBlock:(void (^)(NSUInteger fileCount, NSUInte
486490
}
487491

488492
if (completionBlock) {
489-
dispatch_main_sync_safe(^{
493+
dispatch_async(dispatch_get_main_queue(), ^{
490494
completionBlock(fileCount, totalSize);
491495
});
492496
}

0 commit comments

Comments
 (0)