Authored by DreamPiggy

Fix potential thread-safe problem in SDWebImagePrefetcher by keeping all access …

…through prefetcher queue and retain the local URLs firstly
@@ -55,9 +55,12 @@ @@ -55,9 +55,12 @@
55 } 55 }
56 56
57 - (void)startPrefetchingAtIndex:(NSUInteger)index { 57 - (void)startPrefetchingAtIndex:(NSUInteger)index {
58 - if (index >= self.prefetchURLs.count) return;  
59 - self.requestedCount++;  
60 - NSURL *currentURL = self.prefetchURLs[index]; 58 + NSURL *currentURL;
  59 + @synchronized(self) {
  60 + if (index >= self.prefetchURLs.count) return;
  61 + currentURL = self.prefetchURLs[index];
  62 + self.requestedCount++;
  63 + }
61 [self.manager loadImageWithURL:currentURL options:self.options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 64 [self.manager loadImageWithURL:currentURL options:self.options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
62 if (!finished) return; 65 if (!finished) return;
63 self.finishedCount++; 66 self.finishedCount++;
@@ -77,7 +80,7 @@ @@ -77,7 +80,7 @@
77 ]; 80 ];
78 } 81 }
79 if (self.prefetchURLs.count > self.requestedCount) { 82 if (self.prefetchURLs.count > self.requestedCount) {
80 - dispatch_async(self.prefetcherQueue, ^{ 83 + dispatch_queue_async_safe(self.prefetcherQueue, ^{
81 [self startPrefetchingAtIndex:self.requestedCount]; 84 [self startPrefetchingAtIndex:self.requestedCount];
82 }); 85 });
83 } else if (self.finishedCount == self.requestedCount) { 86 } else if (self.finishedCount == self.requestedCount) {
@@ -128,10 +131,12 @@ @@ -128,10 +131,12 @@
128 } 131 }
129 132
130 - (void)cancelPrefetching { 133 - (void)cancelPrefetching {
131 - self.prefetchURLs = nil;  
132 - self.skippedCount = 0;  
133 - self.requestedCount = 0;  
134 - self.finishedCount = 0; 134 + @synchronized(self) {
  135 + self.prefetchURLs = nil;
  136 + self.skippedCount = 0;
  137 + self.requestedCount = 0;
  138 + self.finishedCount = 0;
  139 + }
135 [self.manager cancelAll]; 140 [self.manager cancelAll];
136 } 141 }
137 142