Authored by Olivier Poitrey

Merge pull request #727 from kejinlu/master

It's generally a bad idea to remove items from a container while iterating through it.
@@ -358,7 +358,7 @@ BOOL ImageDataHasPNGPreffix(NSData *data) { @@ -358,7 +358,7 @@ BOOL ImageDataHasPNGPreffix(NSData *data) {
358 } 358 }
359 359
360 - (void)cleanDiskWithCompletionBlock:(void (^)())completionBlock { 360 - (void)cleanDiskWithCompletionBlock:(void (^)())completionBlock {
361 - dispatch_async(self.ioQueue, ^{ 361 + dispatch_barrier_async(self.ioQueue, ^{
362 NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES]; 362 NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];
363 NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey]; 363 NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey];
364 364
@@ -376,6 +376,7 @@ BOOL ImageDataHasPNGPreffix(NSData *data) { @@ -376,6 +376,7 @@ BOOL ImageDataHasPNGPreffix(NSData *data) {
376 // 376 //
377 // 1. Removing files that are older than the expiration date. 377 // 1. Removing files that are older than the expiration date.
378 // 2. Storing file attributes for the size-based cleanup pass. 378 // 2. Storing file attributes for the size-based cleanup pass.
  379 + NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init];
379 for (NSURL *fileURL in fileEnumerator) { 380 for (NSURL *fileURL in fileEnumerator) {
380 NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL]; 381 NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL];
381 382
@@ -387,7 +388,7 @@ BOOL ImageDataHasPNGPreffix(NSData *data) { @@ -387,7 +388,7 @@ BOOL ImageDataHasPNGPreffix(NSData *data) {
387 // Remove files that are older than the expiration date; 388 // Remove files that are older than the expiration date;
388 NSDate *modificationDate = resourceValues[NSURLContentModificationDateKey]; 389 NSDate *modificationDate = resourceValues[NSURLContentModificationDateKey];
389 if ([[modificationDate laterDate:expirationDate] isEqualToDate:expirationDate]) { 390 if ([[modificationDate laterDate:expirationDate] isEqualToDate:expirationDate]) {
390 - [_fileManager removeItemAtURL:fileURL error:nil]; 391 + [urlsToDelete addObject:fileURL];
391 continue; 392 continue;
392 } 393 }
393 394
@@ -396,6 +397,10 @@ BOOL ImageDataHasPNGPreffix(NSData *data) { @@ -396,6 +397,10 @@ BOOL ImageDataHasPNGPreffix(NSData *data) {
396 currentCacheSize += [totalAllocatedSize unsignedIntegerValue]; 397 currentCacheSize += [totalAllocatedSize unsignedIntegerValue];
397 [cacheFiles setObject:resourceValues forKey:fileURL]; 398 [cacheFiles setObject:resourceValues forKey:fileURL];
398 } 399 }
  400 +
  401 + for (NSURL *fileURL in urlsToDelete) {
  402 + [_fileManager removeItemAtURL:fileURL error:nil];
  403 + }
399 404
400 // If our remaining disk cache exceeds a configured maximum size, perform a second 405 // If our remaining disk cache exceeds a configured maximum size, perform a second
401 // size-based cleanup pass. We delete the oldest files first. 406 // size-based cleanup pass. We delete the oldest files first.