Merge pull request #2645 from zhongwuzw/fix_prefetch_hung_up
Fix prefetch hung up
This commit is contained in:
commit
07204d5a60
|
@ -10,14 +10,17 @@
|
||||||
|
|
||||||
@interface SDAsyncBlockOperation ()
|
@interface SDAsyncBlockOperation ()
|
||||||
|
|
||||||
@property (nonatomic, assign) BOOL isExecuting;
|
@property (assign, nonatomic, getter = isExecuting) BOOL executing;
|
||||||
@property (nonatomic, assign) BOOL isFinished;
|
@property (assign, nonatomic, getter = isFinished) BOOL finished;
|
||||||
@property (nonatomic, copy, nonnull) SDAsyncBlock executionBlock;
|
@property (nonatomic, copy, nonnull) SDAsyncBlock executionBlock;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation SDAsyncBlockOperation
|
@implementation SDAsyncBlockOperation
|
||||||
|
|
||||||
|
@synthesize executing = _executing;
|
||||||
|
@synthesize finished = _finished;
|
||||||
|
|
||||||
- (nonnull instancetype)initWithBlock:(nonnull SDAsyncBlock)block {
|
- (nonnull instancetype)initWithBlock:(nonnull SDAsyncBlock)block {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self) {
|
||||||
|
@ -32,8 +35,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)start {
|
- (void)start {
|
||||||
|
if (self.isCancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
[self willChangeValueForKey:@"isExecuting"];
|
[self willChangeValueForKey:@"isExecuting"];
|
||||||
self.isExecuting = YES;
|
self.executing = YES;
|
||||||
[self didChangeValueForKey:@"isExecuting"];
|
[self didChangeValueForKey:@"isExecuting"];
|
||||||
|
|
||||||
if (self.executionBlock) {
|
if (self.executionBlock) {
|
||||||
|
@ -43,11 +50,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)cancel {
|
||||||
|
[super cancel];
|
||||||
|
[self complete];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)complete {
|
- (void)complete {
|
||||||
[self willChangeValueForKey:@"isExecuting"];
|
[self willChangeValueForKey:@"isExecuting"];
|
||||||
[self willChangeValueForKey:@"isFinished"];
|
[self willChangeValueForKey:@"isFinished"];
|
||||||
self.isExecuting = NO;
|
self.executing = NO;
|
||||||
self.isFinished = YES;
|
self.finished = YES;
|
||||||
[self didChangeValueForKey:@"isExecuting"];
|
[self didChangeValueForKey:@"isExecuting"];
|
||||||
[self didChangeValueForKey:@"isFinished"];
|
[self didChangeValueForKey:@"isFinished"];
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@property (nonatomic, copy, readwrite) NSArray<NSURL *> *urls;
|
@property (nonatomic, copy, readwrite) NSArray<NSURL *> *urls;
|
||||||
@property (nonatomic, strong) NSPointerArray *operations;
|
@property (nonatomic, strong) NSPointerArray *loadOperations;
|
||||||
|
@property (nonatomic, strong) NSPointerArray *prefetchOperations;
|
||||||
@property (nonatomic, weak) SDWebImagePrefetcher *prefetcher;
|
@property (nonatomic, weak) SDWebImagePrefetcher *prefetcher;
|
||||||
@property (nonatomic, copy, nullable) SDWebImagePrefetcherCompletionBlock completionBlock;
|
@property (nonatomic, copy, nullable) SDWebImagePrefetcherCompletionBlock completionBlock;
|
||||||
@property (nonatomic, copy, nullable) SDWebImagePrefetcherProgressBlock progressBlock;
|
@property (nonatomic, copy, nullable) SDWebImagePrefetcherProgressBlock progressBlock;
|
||||||
|
@ -93,7 +94,8 @@
|
||||||
token->_finishedCount = 0;
|
token->_finishedCount = 0;
|
||||||
token->_totalCount = token.urls.count;
|
token->_totalCount = token.urls.count;
|
||||||
atomic_flag_clear(&(token->_isAllFinished));
|
atomic_flag_clear(&(token->_isAllFinished));
|
||||||
token.operations = [NSPointerArray weakObjectsPointerArray];
|
token.loadOperations = [NSPointerArray weakObjectsPointerArray];
|
||||||
|
token.prefetchOperations = [NSPointerArray weakObjectsPointerArray];
|
||||||
token.progressBlock = progressBlock;
|
token.progressBlock = progressBlock;
|
||||||
token.completionBlock = completionBlock;
|
token.completionBlock = completionBlock;
|
||||||
[self addRunningToken:token];
|
[self addRunningToken:token];
|
||||||
|
@ -103,12 +105,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startPrefetchWithToken:(SDWebImagePrefetchToken * _Nonnull)token {
|
- (void)startPrefetchWithToken:(SDWebImagePrefetchToken * _Nonnull)token {
|
||||||
NSPointerArray *operations = token.operations;
|
NSPointerArray *operations = token.loadOperations;
|
||||||
for (NSURL *url in token.urls) {
|
for (NSURL *url in token.urls) {
|
||||||
__weak typeof(self) wself = self;
|
__weak typeof(self) wself = self;
|
||||||
SDAsyncBlockOperation *prefetchOperation = [SDAsyncBlockOperation blockOperationWithBlock:^(SDAsyncBlockOperation * _Nonnull asyncOperation) {
|
SDAsyncBlockOperation *prefetchOperation = [SDAsyncBlockOperation blockOperationWithBlock:^(SDAsyncBlockOperation * _Nonnull asyncOperation) {
|
||||||
__strong typeof(wself) strongSelf = wself;
|
__strong typeof(wself) strongSelf = wself;
|
||||||
if (!strongSelf) {
|
if (!strongSelf || asyncOperation.isCancelled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
id<SDWebImageOperation> operation = [strongSelf.manager loadImageWithURL:url options:strongSelf.options context:strongSelf.context progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
|
id<SDWebImageOperation> operation = [strongSelf.manager loadImageWithURL:url options:strongSelf.options context:strongSelf.context progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
|
||||||
|
@ -119,7 +121,6 @@
|
||||||
if (!finished) {
|
if (!finished) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[asyncOperation complete];
|
|
||||||
|
|
||||||
atomic_fetch_add_explicit(&(token->_finishedCount), 1, memory_order_relaxed);
|
atomic_fetch_add_explicit(&(token->_finishedCount), 1, memory_order_relaxed);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -137,11 +138,16 @@
|
||||||
[sself removeRunningToken:token];
|
[sself removeRunningToken:token];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[asyncOperation complete];
|
||||||
}];
|
}];
|
||||||
|
NSAssert(operation != nil, @"Operation should not be nil, [SDWebImageManager loadImageWithURL:options:context:progress:completed:] break prefetch logic");
|
||||||
@synchronized (token) {
|
@synchronized (token) {
|
||||||
[operations addPointer:(__bridge void *)operation];
|
[operations addPointer:(__bridge void *)operation];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
@synchronized (token) {
|
||||||
|
[token.prefetchOperations addPointer:(__bridge void *)prefetchOperation];
|
||||||
|
}
|
||||||
[self.prefetchQueue addOperation:prefetchOperation];
|
[self.prefetchQueue addOperation:prefetchOperation];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,12 +262,21 @@
|
||||||
|
|
||||||
- (void)cancel {
|
- (void)cancel {
|
||||||
@synchronized (self) {
|
@synchronized (self) {
|
||||||
for (id operation in self.operations) {
|
[self.prefetchOperations compact];
|
||||||
|
for (id operation in self.prefetchOperations) {
|
||||||
if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]) {
|
if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]) {
|
||||||
[operation cancel];
|
[operation cancel];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.operations.count = 0;
|
self.prefetchOperations.count = 0;
|
||||||
|
|
||||||
|
[self.loadOperations compact];
|
||||||
|
for (id operation in self.loadOperations) {
|
||||||
|
if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]) {
|
||||||
|
[operation cancel];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.loadOperations.count = 0;
|
||||||
}
|
}
|
||||||
self.completionBlock = nil;
|
self.completionBlock = nil;
|
||||||
self.progressBlock = nil;
|
self.progressBlock = nil;
|
||||||
|
|
Loading…
Reference in New Issue