Skip to content

Commit d26d470

Browse files
ndfredfacebook-github-bot-6
authored andcommitted
Implement cancellation for RCTAssetsLibraryImageLoader
Reviewed By: @tadeuzagallo Differential Revision: D2471253
1 parent 98378ca commit d26d470

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

Libraries/CameraRoll/RCTAssetsLibraryImageLoader.m

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#import <AssetsLibrary/AssetsLibrary.h>
1313
#import <ImageIO/ImageIO.h>
14+
#import <libkern/OSAtomic.h>
1415
#import <UIKit/UIKit.h>
1516

1617
#import "RCTBridge.h"
@@ -45,17 +46,26 @@ - (BOOL)canLoadImageURL:(NSURL *)requestURL
4546

4647
- (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL size:(CGSize)size scale:(CGFloat)scale resizeMode:(UIViewContentMode)resizeMode progressHandler:(RCTImageLoaderProgressBlock)progressHandler completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
4748
{
49+
__block volatile uint32_t cancelled = 0;
50+
4851
[[self assetsLibrary] assetForURL:imageURL resultBlock:^(ALAsset *asset) {
52+
if (cancelled) {
53+
return;
54+
}
55+
4956
if (asset) {
5057
// ALAssetLibrary API is async and will be multi-threaded. Loading a few full
5158
// resolution images at once will spike the memory up to store the image data,
5259
// and might trigger memory warnings and/or OOM crashes.
5360
// To improve this, process the loaded asset in a serial queue.
5461
dispatch_async(RCTAssetsLibraryImageLoaderQueue(), ^{
62+
if (cancelled) {
63+
return;
64+
}
65+
5566
// Also make sure the image is released immediately after it's used so it
5667
// doesn't spike the memory up during the process.
5768
@autoreleasepool {
58-
5969
BOOL useMaximumSize = CGSizeEqualToSize(size, CGSizeZero);
6070
ALAssetRepresentation *representation = [asset defaultRepresentation];
6171

@@ -78,12 +88,18 @@ - (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL size:(CGSiz
7888
completionHandler(error, nil);
7989
}
8090
} failureBlock:^(NSError *loadError) {
91+
if (cancelled) {
92+
return;
93+
}
94+
8195
NSString *errorText = [NSString stringWithFormat:@"Failed to load asset at URL %@.\niOS Error: %@", imageURL, loadError];
8296
NSError *error = RCTErrorWithMessage(errorText);
8397
completionHandler(error, nil);
8498
}];
8599

86-
return ^{};
100+
return ^{
101+
OSAtomicOr32Barrier(1, &cancelled);
102+
};
87103
}
88104

89105
@end

0 commit comments

Comments
 (0)