Replacing #781 - made sure all the completionBlocks called from `SDWebImageDownloaderOperation` are called on the main queue. Created 2 methods to simplify the code for calling the completions
This commit is contained in:
parent
f7e8246014
commit
c77adf449a
|
@ -102,7 +102,7 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
|
||||||
callbacks = [[self.callbackBlocks valueForKey:key] mutableCopy];
|
callbacks = [[self.callbackBlocks valueForKey:key] mutableCopy];
|
||||||
[callbacks removeObjectIdenticalTo:[NSNull null]];
|
[callbacks removeObjectIdenticalTo:[NSNull null]];
|
||||||
});
|
});
|
||||||
return callbacks;
|
return [callbacks copy]; // strip mutability here
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)cancel:(nullable id)token {
|
- (BOOL)cancel:(nullable id)token {
|
||||||
|
@ -175,9 +175,7 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:self];
|
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:self];
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
for (SDWebImageDownloaderCompletedBlock completedBlock in [self callbacksForKey:kCompletedCallbackKey]) {
|
[self callCompletionBlocksWithError:[NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Connection can't be initialized"}]];
|
||||||
completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Connection can't be initialized"}], YES);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SD_UIKIT
|
#if SD_UIKIT
|
||||||
|
@ -286,10 +284,9 @@ didReceiveResponse:(NSURLResponse *)response
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self];
|
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
[self callCompletionBlocksWithError:[NSError errorWithDomain:NSURLErrorDomain code:((NSHTTPURLResponse *)response).statusCode userInfo:nil]];
|
||||||
|
|
||||||
for (SDWebImageDownloaderCompletedBlock completedBlock in [self callbacksForKey:kCompletedCallbackKey]) {
|
|
||||||
completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:((NSHTTPURLResponse *)response).statusCode userInfo:nil], YES);
|
|
||||||
}
|
|
||||||
[self done];
|
[self done];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,11 +369,8 @@ didReceiveResponse:(NSURLResponse *)response
|
||||||
image = scaledImage;
|
image = scaledImage;
|
||||||
}
|
}
|
||||||
CGImageRelease(partialImageRef);
|
CGImageRelease(partialImageRef);
|
||||||
dispatch_main_async_safe(^{
|
|
||||||
for (SDWebImageDownloaderCompletedBlock completedBlock in [self callbacksForKey:kCompletedCallbackKey]) {
|
[self callCompletionBlocksWithImage:image imageData:nil error:nil finished:NO];
|
||||||
completedBlock(image, nil, nil, NO);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +402,6 @@ didReceiveResponse:(NSURLResponse *)response
|
||||||
#pragma mark NSURLSessionTaskDelegate
|
#pragma mark NSURLSessionTaskDelegate
|
||||||
|
|
||||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
|
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
|
||||||
NSArray<id> *completionBlocks = [[self callbacksForKey:kCompletedCallbackKey] copy];
|
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
self.dataTask = nil;
|
self.dataTask = nil;
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
@ -420,11 +413,9 @@ didReceiveResponse:(NSURLResponse *)response
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
for (SDWebImageDownloaderCompletedBlock completionBlock in completionBlocks) {
|
[self callCompletionBlocksWithError:error];
|
||||||
completionBlock(nil, nil, error, YES);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (completionBlocks.count > 0) {
|
if ([self callbacksForKey:kCompletedCallbackKey].count > 0) {
|
||||||
/**
|
/**
|
||||||
* See #1608 and #1623 - apparently, there is a race condition on `NSURLCache` that causes a crash
|
* See #1608 and #1623 - apparently, there is a race condition on `NSURLCache` that causes a crash
|
||||||
* Limited the calls to `cachedResponseForRequest:` only for cases where we should ignore the cached response
|
* Limited the calls to `cachedResponseForRequest:` only for cases where we should ignore the cached response
|
||||||
|
@ -432,9 +423,8 @@ didReceiveResponse:(NSURLResponse *)response
|
||||||
* Note: responseFromCached is set to NO inside `willCacheResponse:`. This method doesn't get called for large images or images behind authentication
|
* Note: responseFromCached is set to NO inside `willCacheResponse:`. This method doesn't get called for large images or images behind authentication
|
||||||
*/
|
*/
|
||||||
if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached && [[NSURLCache sharedURLCache] cachedResponseForRequest:self.request]) {
|
if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached && [[NSURLCache sharedURLCache] cachedResponseForRequest:self.request]) {
|
||||||
for (SDWebImageDownloaderCompletedBlock completionBlock in completionBlocks) {
|
// hack
|
||||||
completionBlock(nil, nil, nil, YES);
|
[self callCompletionBlocksWithImage:nil imageData:nil error:nil finished:YES];
|
||||||
}
|
|
||||||
} else if (self.imageData) {
|
} else if (self.imageData) {
|
||||||
UIImage *image = [UIImage sd_imageWithData:self.imageData];
|
UIImage *image = [UIImage sd_imageWithData:self.imageData];
|
||||||
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL];
|
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL];
|
||||||
|
@ -447,18 +437,12 @@ didReceiveResponse:(NSURLResponse *)response
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CGSizeEqualToSize(image.size, CGSizeZero)) {
|
if (CGSizeEqualToSize(image.size, CGSizeZero)) {
|
||||||
for (SDWebImageDownloaderCompletedBlock completionBlock in completionBlocks) {
|
[self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}]];
|
||||||
completionBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}], YES);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (SDWebImageDownloaderCompletedBlock completionBlock in completionBlocks) {
|
[self callCompletionBlocksWithImage:image imageData:self.imageData error:nil finished:YES];
|
||||||
completionBlock(image, self.imageData, nil, YES);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (SDWebImageDownloaderCompletedBlock completionBlock in completionBlocks) {
|
[self callCompletionBlocksWithError:[NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Image data is nil"}]];
|
||||||
completionBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Image data is nil"}], YES);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -530,4 +514,20 @@ didReceiveResponse:(NSURLResponse *)response
|
||||||
return self.options & SDWebImageDownloaderContinueInBackground;
|
return self.options & SDWebImageDownloaderContinueInBackground;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)callCompletionBlocksWithError:(nullable NSError *)error {
|
||||||
|
[self callCompletionBlocksWithImage:nil imageData:nil error:error finished:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)callCompletionBlocksWithImage:(nullable UIImage *)image
|
||||||
|
imageData:(nullable NSData *)imageData
|
||||||
|
error:(nullable NSError *)error
|
||||||
|
finished:(BOOL)finished {
|
||||||
|
NSArray<id> *completionBlocks = [self callbacksForKey:kCompletedCallbackKey];
|
||||||
|
dispatch_main_async_safe(^{
|
||||||
|
for (SDWebImageDownloaderCompletedBlock completedBlock in completionBlocks) {
|
||||||
|
completedBlock(image, imageData, error, finished);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Reference in New Issue