Skip to content

Commit e362fb2

Browse files
committed
[ReactNative] Move image asset loading to a queue
1 parent 758dd0d commit e362fb2

1 file changed

Lines changed: 27 additions & 4 deletions

File tree

Libraries/Image/RCTImageLoader.m

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@
1919
#import "RCTImageDownloader.h"
2020
#import "RCTLog.h"
2121

22+
static dispatch_queue_t RCTImageLoaderQueue(void)
23+
{
24+
static dispatch_queue_t queue = NULL;
25+
static dispatch_once_t onceToken;
26+
dispatch_once(&onceToken, ^{
27+
queue = dispatch_queue_create("com.facebook.rctImageLoader", DISPATCH_QUEUE_SERIAL);
28+
dispatch_set_target_queue(queue,
29+
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
30+
});
31+
32+
return queue;
33+
}
34+
2235
NSError *errorWithMessage(NSString *message)
2336
{
2437
NSDictionary *errorInfo = @{NSLocalizedDescriptionKey: message};
@@ -43,10 +56,20 @@ + (void)loadImageWithTag:(NSString *)imageTag callback:(void (^)(NSError *error,
4356
if ([imageTag hasPrefix:@"assets-library"]) {
4457
[[RCTImageLoader assetsLibrary] assetForURL:[NSURL URLWithString:imageTag] resultBlock:^(ALAsset *asset) {
4558
if (asset) {
46-
ALAssetRepresentation *representation = [asset defaultRepresentation];
47-
ALAssetOrientation orientation = [representation orientation];
48-
UIImage *image = [UIImage imageWithCGImage:[representation fullResolutionImage] scale:1.0f orientation:(UIImageOrientation)orientation];
49-
callback(nil, image);
59+
// ALAssetLibrary API is async and will be multi-threaded. Loading a few full
60+
// resolution images at once will spike the memory up to store the image data,
61+
// and might trigger memory warnings and/or OOM crashes.
62+
// To improve this, process the loaded asset in a serial queue.
63+
dispatch_async(RCTImageLoaderQueue(), ^{
64+
// Also make sure the image is released immediately after it's used so it
65+
// doesn't spike the memory up during the process.
66+
@autoreleasepool {
67+
ALAssetRepresentation *representation = [asset defaultRepresentation];
68+
ALAssetOrientation orientation = [representation orientation];
69+
UIImage *image = [UIImage imageWithCGImage:[representation fullResolutionImage] scale:1.0f orientation:(UIImageOrientation)orientation];
70+
callback(nil, image);
71+
}
72+
});
5073
} else {
5174
NSString *errorText = [NSString stringWithFormat:@"Failed to load asset at URL %@ with no error message.", imageTag];
5275
NSError *error = errorWithMessage(errorText);

0 commit comments

Comments
 (0)