Authored by Bogdan Poplauschi

Replace #699 Fixed race condition in SDWebImageManager if one operation is cance…

…lled, the completion block must not be called, otherwise it might race with a newer completion for the same object

Conflicts:
	SDWebImage/SDWebImageManager.m
@@ -181,13 +181,15 @@ @@ -181,13 +181,15 @@
181 } 181 }
182 id <SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { 182 id <SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) {
183 if (weakOperation.isCancelled) { 183 if (weakOperation.isCancelled) {
184 - dispatch_main_sync_safe(^{  
185 - completedBlock(nil, nil, SDImageCacheTypeNone, finished, url);  
186 - }); 184 + // Do nothing if the operation was cancelled
  185 + // See #699 for more details
  186 + // 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
187 } 187 }
188 else if (error) { 188 else if (error) {
189 dispatch_main_sync_safe(^{ 189 dispatch_main_sync_safe(^{
  190 + if (!weakOperation.isCancelled) {
190 completedBlock(nil, error, SDImageCacheTypeNone, finished, url); 191 completedBlock(nil, error, SDImageCacheTypeNone, finished, url);
  192 + }
191 }); 193 });
192 194
193 if (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut) { 195 if (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut) {
@@ -213,7 +215,9 @@ @@ -213,7 +215,9 @@
213 } 215 }
214 216
215 dispatch_main_sync_safe(^{ 217 dispatch_main_sync_safe(^{
  218 + if (!weakOperation.isCancelled) {
216 completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url); 219 completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url);
  220 + }
217 }); 221 });
218 }); 222 });
219 } 223 }
@@ -223,7 +227,9 @@ @@ -223,7 +227,9 @@
223 } 227 }
224 228
225 dispatch_main_sync_safe(^{ 229 dispatch_main_sync_safe(^{
  230 + if (!weakOperation.isCancelled) {
226 completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url); 231 completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url);
  232 + }
227 }); 233 });
228 } 234 }
229 } 235 }
@@ -244,7 +250,9 @@ @@ -244,7 +250,9 @@
244 } 250 }
245 else if (image) { 251 else if (image) {
246 dispatch_main_sync_safe(^{ 252 dispatch_main_sync_safe(^{
  253 + if (!weakOperation.isCancelled) {
247 completedBlock(image, nil, cacheType, YES, url); 254 completedBlock(image, nil, cacheType, YES, url);
  255 + }
248 }); 256 });
249 @synchronized (self.runningOperations) { 257 @synchronized (self.runningOperations) {
250 [self.runningOperations removeObject:operation]; 258 [self.runningOperations removeObject:operation];
@@ -253,7 +261,9 @@ @@ -253,7 +261,9 @@
253 else { 261 else {
254 // Image not in cache and download disallowed by delegate 262 // Image not in cache and download disallowed by delegate
255 dispatch_main_sync_safe(^{ 263 dispatch_main_sync_safe(^{
  264 + if (!weakOperation.isCancelled) {
256 completedBlock(nil, nil, SDImageCacheTypeNone, YES, url); 265 completedBlock(nil, nil, SDImageCacheTypeNone, YES, url);
  266 + }
257 }); 267 });
258 @synchronized (self.runningOperations) { 268 @synchronized (self.runningOperations) {
259 [self.runningOperations removeObject:operation]; 269 [self.runningOperations removeObject:operation];