From f080e38fb8e77027617d854a02c0e9df487fdabd Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Tue, 24 Jun 2014 23:36:34 +0300 Subject: [PATCH] Replace #699 Fixed race condition in SDWebImageManager if one operation is cancelled, the completion block must not be called, otherwise it might race with a newer completion for the same object Conflicts: SDWebImage/SDWebImageManager.m --- SDWebImage/SDWebImageManager.m | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index fd48529f..6c75159f 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -181,13 +181,15 @@ } id subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { if (weakOperation.isCancelled) { - dispatch_main_sync_safe(^{ - completedBlock(nil, nil, SDImageCacheTypeNone, finished, url); - }); + // Do nothing if the operation was cancelled + // See #699 for more details + // if we would call the completedBlock, there could be a race condition between this block and another completedBlock for the same object, so if this one is called second, we will overwrite the new data } else if (error) { dispatch_main_sync_safe(^{ - completedBlock(nil, error, SDImageCacheTypeNone, finished, url); + if (!weakOperation.isCancelled) { + completedBlock(nil, error, SDImageCacheTypeNone, finished, url); + } }); if (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut) { @@ -213,7 +215,9 @@ } dispatch_main_sync_safe(^{ - completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url); + if (!weakOperation.isCancelled) { + completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url); + } }); }); } @@ -223,7 +227,9 @@ } dispatch_main_sync_safe(^{ - completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url); + if (!weakOperation.isCancelled) { + completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url); + } }); } } @@ -244,7 +250,9 @@ } else if (image) { dispatch_main_sync_safe(^{ - completedBlock(image, nil, cacheType, YES, url); + if (!weakOperation.isCancelled) { + completedBlock(image, nil, cacheType, YES, url); + } }); @synchronized (self.runningOperations) { [self.runningOperations removeObject:operation]; @@ -253,7 +261,9 @@ else { // Image not in cache and download disallowed by delegate dispatch_main_sync_safe(^{ - completedBlock(nil, nil, SDImageCacheTypeNone, YES, url); + if (!weakOperation.isCancelled) { + completedBlock(nil, nil, SDImageCacheTypeNone, YES, url); + } }); @synchronized (self.runningOperations) { [self.runningOperations removeObject:operation];