diff --git a/Libraries/Image/RCTImageLoader.m b/Libraries/Image/RCTImageLoader.m index 8aee148d44e1de..5f36f84516682d 100644 --- a/Libraries/Image/RCTImageLoader.m +++ b/Libraries/Image/RCTImageLoader.m @@ -440,7 +440,9 @@ - (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request // Download image __weak __typeof(self) weakSelf = self; - RCTNetworkTask *task = [networking networkTaskWithRequest:request completionBlock:^(NSURLResponse *response, NSData *data, NSError *error) { + __block RCTNetworkTask *task = + [networking networkTaskWithRequest:request + completionBlock:^(NSURLResponse *response, NSData *data, NSError *error) { __typeof(self) strongSelf = weakSelf; if (!strongSelf) { return; @@ -480,8 +482,15 @@ - (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request } return ^{ - [task cancel]; - [weakSelf dequeueTasks]; + __typeof(self) strongSelf = weakSelf; + if (!strongSelf || !task) { + return; + } + dispatch_async(strongSelf->_URLRequestQueue, ^{ + [task cancel]; + task = nil; + }); + [strongSelf dequeueTasks]; }; } @@ -496,7 +505,7 @@ - (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)image __block volatile uint32_t cancelled = 0; __block dispatch_block_t cancelLoad = nil; dispatch_block_t cancellationBlock = ^{ - if (cancelLoad) { + if (cancelLoad && !cancelled) { cancelLoad(); } OSAtomicOr32Barrier(1, &cancelled); diff --git a/Libraries/Network/RCTNetworkTask.m b/Libraries/Network/RCTNetworkTask.m index 3438143b6dae29..1a177fca0608bf 100644 --- a/Libraries/Network/RCTNetworkTask.m +++ b/Libraries/Network/RCTNetworkTask.m @@ -53,6 +53,7 @@ - (void)invalidate _incrementalDataBlock = nil; _responseBlock = nil; _uploadProgressBlock = nil; + _requestToken = nil; } - (void)dispatchCallback:(dispatch_block_t)callback @@ -66,6 +67,11 @@ - (void)dispatchCallback:(dispatch_block_t)callback - (void)start { + if (_status != RCTNetworkTaskPending) { + RCTLogError(@"RCTNetworkTask was already started or completed"); + return; + } + if (_requestToken == nil) { id token = [_handler sendRequest:_request withDelegate:self]; if ([self validateRequestToken:token]) { @@ -77,6 +83,10 @@ - (void)start - (void)cancel { + if (_status == RCTNetworkTaskFinished) { + return; + } + _status = RCTNetworkTaskFinished; id token = _requestToken; if (token && [_handler respondsToSelector:@selector(cancelRequest:)]) {