Skip to content

Commit dcca215

Browse files
committed
Use NSOperation instead GCD, high level, supports cancel and add only if queue is empty (to avoid too frequent callback), don't need to create AutoReleasePool as well
1 parent eca8d10 commit dcca215

File tree

1 file changed

+26
-27
lines changed

1 file changed

+26
-27
lines changed

Storage/FirebaseStorageUI/FUIStorageImageLoader.m

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -87,29 +87,28 @@ - (BOOL)canRequestImageForURL:(NSURL *)url {
8787
}
8888
// Download the image from Firebase Storage
8989
// Each download task use independent serial coder queue, to ensure callback in order during prorgessive decoding
90-
dispatch_queue_t coderQueue = dispatch_queue_create("com.google.firebaseui.storage.coderQueue", DISPATCH_QUEUE_SERIAL);
91-
FIRStorageDownloadTask * download = [storageRef dataWithMaxSize:size
92-
completion:^(NSData * _Nullable data, NSError * _Nullable error) {
93-
if (error) {
94-
dispatch_main_async_safe(^{
95-
if (completedBlock) {
96-
completedBlock(nil, nil, error, YES);
97-
}
98-
});
99-
return;
100-
}
101-
// Decode the image with data
102-
dispatch_async(coderQueue, ^{
103-
@autoreleasepool {
104-
UIImage *image = SDImageLoaderDecodeImageData(data, url, options, context);
105-
dispatch_main_async_safe(^{
106-
if (completedBlock) {
107-
completedBlock(image, data, nil, YES);
108-
}
109-
});
110-
}
111-
});
112-
}];
90+
NSOperationQueue *coderQueue = [NSOperationQueue new];
91+
coderQueue.maxConcurrentOperationCount = 1;
92+
FIRStorageDownloadTask * download = [storageRef dataWithMaxSize:size completion:^(NSData * _Nullable data, NSError * _Nullable error) {
93+
if (error) {
94+
dispatch_main_async_safe(^{
95+
if (completedBlock) {
96+
completedBlock(nil, nil, error, YES);
97+
}
98+
});
99+
return;
100+
}
101+
// Decode the image with data
102+
[coderQueue cancelAllOperations];
103+
[coderQueue addOperationWithBlock:^{
104+
UIImage *image = SDImageLoaderDecodeImageData(data, url, options, context);
105+
dispatch_main_async_safe(^{
106+
if (completedBlock) {
107+
completedBlock(image, data, nil, YES);
108+
}
109+
});
110+
}];
111+
}];
113112
// Observe the progress changes
114113
[download observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot * _Nonnull snapshot) {
115114
// Check progressive decoding if need
@@ -128,8 +127,8 @@ - (BOOL)canRequestImageForURL:(NSURL *)url {
128127
// Get the finish status
129128
BOOL finished = receivedSize >= expectedSize;
130129
// This progress block may be called on main queue or global queue (depends configuration), always dispatched on coder queue
131-
dispatch_async(coderQueue, ^{
132-
@autoreleasepool {
130+
if (coderQueue.operationCount == 0) {
131+
[coderQueue addOperationWithBlock:^{
133132
UIImage *image = SDImageLoaderDecodeProgressiveImageData(partialData, url, finished, task, options, context);
134133
if (image) {
135134
dispatch_main_async_safe(^{
@@ -138,8 +137,8 @@ - (BOOL)canRequestImageForURL:(NSURL *)url {
138137
}
139138
});
140139
}
141-
}
142-
});
140+
}];
141+
}
143142
}
144143
}
145144
NSProgress *progress = snapshot.progress;

0 commit comments

Comments
 (0)