diff --git a/SDWebImage/SDWebImageDownloaderOperation.m b/SDWebImage/SDWebImageDownloaderOperation.m index e019600..cb1cba7 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.m +++ b/SDWebImage/SDWebImageDownloaderOperation.m @@ -22,6 +22,7 @@ @property (assign, nonatomic) long long expectedSize; @property (strong, nonatomic) NSMutableData *imageData; @property (strong, nonatomic) NSURLConnection *connection; +@property (strong, atomic) NSThread *thread; #if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0 @property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundTaskId; @@ -54,34 +55,37 @@ - (void)start { - if (self.isCancelled) + @synchronized(self) { - self.finished = YES; - [self reset]; - return; - } + if (self.isCancelled) + { + self.finished = YES; + [self reset]; + return; + } #if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0 - if ([self shouldContinueWhenAppEntersBackground]) - { - __weak __typeof__(self) wself = self; - self.backgroundTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^ + if ([self shouldContinueWhenAppEntersBackground]) { - __strong __typeof(wself)sself = wself; - - if (sself) + __weak __typeof__(self) wself = self; + self.backgroundTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^ { - [sself cancel]; + __strong __typeof(wself)sself = wself; - [[UIApplication sharedApplication] endBackgroundTask:sself.backgroundTaskId]; - sself.backgroundTaskId = UIBackgroundTaskInvalid; - } - }]; - } + if (sself) + { + [sself cancel]; + + [[UIApplication sharedApplication] endBackgroundTask:sself.backgroundTaskId]; + sself.backgroundTaskId = UIBackgroundTaskInvalid; + } + }]; + } #endif - self.executing = YES; - self.connection = [NSURLConnection.alloc initWithRequest:self.request delegate:self startImmediately:NO]; + self.executing = YES; + self.connection = [NSURLConnection.alloc initWithRequest:self.request delegate:self startImmediately:NO]; + } [self.connection start]; @@ -121,6 +125,27 @@ } - (void)cancel +{ + @synchronized(self) + { + if (self.thread) + { + [self performSelector:@selector(cancelInternalAndStop) onThread:self.thread withObject:nil waitUntilDone:NO]; + } + else + { + [self cancelInternal]; + } + } +} + +- (void)cancelInternalAndStop +{ + [self cancelInternal]; + CFRunLoopStop(CFRunLoopGetCurrent()); +} + +- (void)cancelInternal { if (self.isFinished) return; [super cancel]; @@ -154,6 +179,7 @@ self.progressBlock = nil; self.connection = nil; self.imageData = nil; + self.thread = nil; } - (void)setFinished:(BOOL)finished @@ -280,7 +306,7 @@ CFRelease(imageSource); } - + if (self.progressBlock) { self.progressBlock(self.imageData.length, self.expectedSize); @@ -311,16 +337,16 @@ } else { - + UIImage *image = [UIImage sd_imageWithData:self.imageData]; - + image = [self scaledImageForKey:self.request.URL.absoluteString image:image]; - + if (!image.images) // Do not force decod animated GIFs { image = [UIImage decodedImageWithImage:image]; } - + if (CGSizeEqualToSize(image.size, CGSizeZero)) { completionBlock(nil, nil, [NSError errorWithDomain:@"SDWebImageErrorDomain" code:0 userInfo:@{NSLocalizedDescriptionKey: @"Downloaded image has 0 pixels"}], YES); @@ -384,7 +410,7 @@ [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; } - + [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; }