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 + NSURL *currentURL;
  59 + @synchronized(self) {
58 if (index >= self.prefetchURLs.count) return; 60 if (index >= self.prefetchURLs.count) return;
  61 + currentURL = self.prefetchURLs[index];
59 self.requestedCount++; 62 self.requestedCount++;
60 - NSURL *currentURL = self.prefetchURLs[index]; 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 {
  134 + @synchronized(self) {
131 self.prefetchURLs = nil; 135 self.prefetchURLs = nil;
132 self.skippedCount = 0; 136 self.skippedCount = 0;
133 self.requestedCount = 0; 137 self.requestedCount = 0;
134 self.finishedCount = 0; 138 self.finishedCount = 0;
  139 + }
135 [self.manager cancelAll]; 140 [self.manager cancelAll];
136 } 141 }
137 142