diff --git a/SDWebImage/Core/SDWebImagePrefetcher.m b/SDWebImage/Core/SDWebImagePrefetcher.m index b6632fa6..91cbd9a7 100644 --- a/SDWebImage/Core/SDWebImagePrefetcher.m +++ b/SDWebImage/Core/SDWebImagePrefetcher.m @@ -111,49 +111,47 @@ - (void)startPrefetchWithToken:(SDWebImagePrefetchToken * _Nonnull)token { for (NSURL *url in token.urls) { - @autoreleasepool { - @weakify(self); - SDAsyncBlockOperation *prefetchOperation = [SDAsyncBlockOperation blockOperationWithBlock:^(SDAsyncBlockOperation * _Nonnull asyncOperation) { + @weakify(self); + SDAsyncBlockOperation *prefetchOperation = [SDAsyncBlockOperation blockOperationWithBlock:^(SDAsyncBlockOperation * _Nonnull asyncOperation) { + @strongify(self); + if (!self || asyncOperation.isCancelled) { + return; + } + id operation = [self.manager loadImageWithURL:url options:self.options context:self.context progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { @strongify(self); - if (!self || asyncOperation.isCancelled) { + if (!self) { return; } - id operation = [self.manager loadImageWithURL:url options:self.options context:self.context progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { - @strongify(self); - if (!self) { - return; + if (!finished) { + return; + } + atomic_fetch_add_explicit(&(token->_finishedCount), 1, memory_order_relaxed); + if (error) { + // Add last failed + atomic_fetch_add_explicit(&(token->_skippedCount), 1, memory_order_relaxed); + } + + // Current operation finished + [self callProgressBlockForToken:token imageURL:imageURL]; + + if (atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed) == token->_totalCount) { + // All finished + if (!atomic_flag_test_and_set_explicit(&(token->_isAllFinished), memory_order_relaxed)) { + [self callCompletionBlockForToken:token]; + [self removeRunningToken:token]; } - if (!finished) { - return; - } - atomic_fetch_add_explicit(&(token->_finishedCount), 1, memory_order_relaxed); - if (error) { - // Add last failed - atomic_fetch_add_explicit(&(token->_skippedCount), 1, memory_order_relaxed); - } - - // Current operation finished - [self callProgressBlockForToken:token imageURL:imageURL]; - - if (atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed) == token->_totalCount) { - // All finished - if (!atomic_flag_test_and_set_explicit(&(token->_isAllFinished), memory_order_relaxed)) { - [self callCompletionBlockForToken:token]; - [self removeRunningToken:token]; - } - } - [asyncOperation complete]; - }]; - NSAssert(operation != nil, @"Operation should not be nil, [SDWebImageManager loadImageWithURL:options:context:progress:completed:] break prefetch logic"); - SD_LOCK(token->_loadOperationsLock); - [token.loadOperations addPointer:(__bridge void *)operation]; - SD_UNLOCK(token->_loadOperationsLock); + } + [asyncOperation complete]; }]; - SD_LOCK(token->_prefetchOperationsLock); - [token.prefetchOperations addPointer:(__bridge void *)prefetchOperation]; - SD_UNLOCK(token->_prefetchOperationsLock); - [self.prefetchQueue addOperation:prefetchOperation]; - } + NSAssert(operation != nil, @"Operation should not be nil, [SDWebImageManager loadImageWithURL:options:context:progress:completed:] break prefetch logic"); + SD_LOCK(token->_loadOperationsLock); + [token.loadOperations addPointer:(__bridge void *)operation]; + SD_UNLOCK(token->_loadOperationsLock); + }]; + SD_LOCK(token->_prefetchOperationsLock); + [token.prefetchOperations addPointer:(__bridge void *)prefetchOperation]; + SD_UNLOCK(token->_prefetchOperationsLock); + [self.prefetchQueue addOperation:prefetchOperation]; } }