Authored by Bogdan Poplauschi

Merge branch 'master' into 4.x

# Conflicts:
#	CHANGELOG.md
#	Examples/SDWebImage Demo/MasterViewController.m
#	SDWebImage.podspec
#	SDWebImage/SDWebImageDownloader.m
#	SDWebImage/SDWebImageDownloaderOperation.m
#	WebImage/Info.plist
@@ -60,6 +60,11 @@ @@ -60,6 +60,11 @@
60 - Fix multiple requests for same image and then canceling one #883 + 8a78586 60 - Fix multiple requests for same image and then canceling one #883 + 8a78586
61 - Fixed #1444 and the master build thanks to [@kenmaz](https://github.com/kenmaz/SDWebImage/commit/5034c334be50765dfe4e97c48bcb74ef64175188) 61 - Fixed #1444 and the master build thanks to [@kenmaz](https://github.com/kenmaz/SDWebImage/commit/5034c334be50765dfe4e97c48bcb74ef64175188)
62 62
  63 +## [3.8.2 Patch release for 3.8.0 on Sep 5th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.8.2)
  64 +
  65 +#### Fixes:
  66 +
  67 +- Fixed #1608 #1623 #1644 Crash in `[NSURLCache cachedResponseForRequest:]` - the fix is actually avoiding to access `NSURLCache` which appears to generate a race condition. We only call it if necesarry (`SDWebImageRefreshCached` is used and the image cannot be cached by the system when it's too big or behind authentication)
63 68
64 ## [3.8.1 Patch release for 3.8.0 on Jun 7th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.8.1) 69 ## [3.8.1 Patch release for 3.8.0 on Jun 7th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.8.1)
65 70
@@ -70,6 +70,7 @@ @@ -70,6 +70,7 @@
70 _executionOrder = SDWebImageDownloaderFIFOExecutionOrder; 70 _executionOrder = SDWebImageDownloaderFIFOExecutionOrder;
71 _downloadQueue = [NSOperationQueue new]; 71 _downloadQueue = [NSOperationQueue new];
72 _downloadQueue.maxConcurrentOperationCount = 6; 72 _downloadQueue.maxConcurrentOperationCount = 6;
  73 + _downloadQueue.name = @"com.hackemist.SDWebImageDownloader";
73 _URLOperations = [NSMutableDictionary new]; 74 _URLOperations = [NSMutableDictionary new];
74 #ifdef SD_WEBP 75 #ifdef SD_WEBP
75 _HTTPHeaders = [@{@"Accept": @"image/webp,image/*;q=0.8"} mutableCopy]; 76 _HTTPHeaders = [@{@"Accept": @"image/webp,image/*;q=0.8"} mutableCopy];
@@ -67,7 +67,7 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary; @@ -67,7 +67,7 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
67 inSession:(nullable NSURLSession *)session 67 inSession:(nullable NSURLSession *)session
68 options:(SDWebImageDownloaderOptions)options { 68 options:(SDWebImageDownloaderOptions)options {
69 if ((self = [super init])) { 69 if ((self = [super init])) {
70 - _request = request; 70 + _request = [request copy];
71 _shouldDecompressImages = YES; 71 _shouldDecompressImages = YES;
72 _options = options; 72 _options = options;
73 _callbackBlocks = [NSMutableArray new]; 73 _callbackBlocks = [NSMutableArray new];
@@ -438,12 +438,14 @@ didReceiveResponse:(NSURLResponse *)response @@ -438,12 +438,14 @@ didReceiveResponse:(NSURLResponse *)response
438 completionBlock(nil, nil, error, YES); 438 completionBlock(nil, nil, error, YES);
439 } 439 }
440 } else { 440 } else {
441 - if (![[NSURLCache sharedURLCache] cachedResponseForRequest:_request]) {  
442 - responseFromCached = NO;  
443 - }  
444 -  
445 if (completionBlocks.count > 0) { 441 if (completionBlocks.count > 0) {
446 - if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached) { 442 + /**
  443 + * See #1608 and #1623 - apparently, there is a race condition on `NSURLCache` that causes a crash
  444 + * Limited the calls to `cachedResponseForRequest:` only for cases where we should ignore the cached response
  445 + * and images for which responseFromCached is YES (only the ones that cannot be cached).
  446 + * Note: responseFromCached is set to NO inside `willCacheResponse:`. This method doesn't get called for large images or images behind authentication
  447 + */
  448 + if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached && [[NSURLCache sharedURLCache] cachedResponseForRequest:self.request]) {
447 for (SDWebImageDownloaderCompletedBlock completionBlock in completionBlocks) { 449 for (SDWebImageDownloaderCompletedBlock completionBlock in completionBlocks) {
448 completionBlock(nil, nil, nil, YES); 450 completionBlock(nil, nil, nil, YES);
449 } 451 }