Skip to content

Commit 9c85524

Browse files
committed
Merge pull request #83 from talko/processimage
Fixes a bug that causes image retrieval to never complete if it depends on an source image URL whose request is already in flight.
2 parents 09de614 + 43ebd60 commit 9c85524

1 file changed

Lines changed: 59 additions & 30 deletions

File tree

FastImageCache/FICImageCache.m

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ - (void)_imageDidLoad:(UIImage *)image forURL:(NSURL *)URL {
250250
NSString *formatName = [entityDictionary objectForKey:FICImageCacheFormatKey];
251251
NSDictionary *completionBlocksDictionary = [entityDictionary objectForKey:FICImageCacheCompletionBlocksKey];
252252
if (image != nil){
253-
[self _processImage:image forEntity:entity withFormatName:formatName completionBlocksDictionary:completionBlocksDictionary];
253+
[self _processImage:image forEntity:entity completionBlocksDictionary:completionBlocksDictionary];
254254
} else {
255255
NSArray *completionBlocks = [completionBlocksDictionary objectForKey:formatName];
256256
if (completionBlocks != nil) {
@@ -314,41 +314,18 @@ - (void)setImage:(UIImage *)image forEntity:(id <FICEntity>)entity withFormatNam
314314
if (imageTable) {
315315
[imageTable deleteEntryForEntityUUID:entityUUID];
316316

317-
[self _processImage:image forEntity:entity withFormatName:formatName completionBlocksDictionary:completionBlocksDictionary];
317+
[self _processImage:image forEntity:entity completionBlocksDictionary:completionBlocksDictionary];
318318
} else {
319319
[self _logMessage:[NSString stringWithFormat:@"*** FIC Error: %s Couldn't find image table with format name %@", __PRETTY_FUNCTION__, formatName]];
320320
}
321321
}
322322
}
323323

324-
- (void)_processImage:(UIImage *)image forEntity:(id <FICEntity>)entity withFormatName:(NSString *)formatName completionBlocksDictionary:(NSDictionary *)completionBlocksDictionary {
325-
FICImageFormat *imageFormat = [_formats objectForKey:formatName];
326-
NSString *formatFamily = [imageFormat family];
327-
NSString *entityUUID = [entity UUID];
328-
NSString *sourceImageUUID = [entity sourceImageUUID];
329-
330-
if (formatFamily != nil) {
331-
BOOL shouldProcessAllFormatsInFamily = YES;
332-
if (_delegateImplementsShouldProcessAllFormatsInFamilyForEntity) {
333-
shouldProcessAllFormatsInFamily = [_delegate imageCache:self shouldProcessAllFormatsInFamily:formatFamily forEntity:entity];
334-
}
335-
// All of the formats in a given family use the same source asset, so once we have that source asset, we can generate all of the family's formats.
336-
for (FICImageTable *table in [_imageTables allValues]) {
337-
FICImageFormat *imageFormat = [table imageFormat];
338-
NSString *tableFormatFamily = [imageFormat family];
339-
if ([formatFamily isEqualToString:tableFormatFamily]) {
340-
NSArray *completionBlocks = [completionBlocksDictionary objectForKey:[imageFormat name]];
341-
342-
BOOL imageExistsForEntity = [table entryExistsForEntityUUID:entityUUID sourceImageUUID:sourceImageUUID];
343-
BOOL shouldProcessFamilyFormat = shouldProcessAllFormatsInFamily && imageExistsForEntity == NO;
344-
if (shouldProcessFamilyFormat || [completionBlocks count] > 0) {
345-
[self _processImage:image forEntity:entity imageTable:table completionBlocks:completionBlocks];
346-
}
347-
}
348-
}
349-
} else {
350-
FICImageTable *imageTable = [_imageTables objectForKey:formatName];
351-
NSArray *completionBlocks = [completionBlocksDictionary objectForKey:formatName];
324+
- (void)_processImage:(UIImage *)image forEntity:(id <FICEntity>)entity completionBlocksDictionary:(NSDictionary *)completionBlocksDictionary {
325+
for (NSString *formatToProcess in [self formatsToProcessForCompletionBlocks:completionBlocksDictionary
326+
entity:entity]) {
327+
FICImageTable *imageTable = [_imageTables objectForKey:formatToProcess];
328+
NSArray *completionBlocks = [completionBlocksDictionary objectForKey:formatToProcess];
352329
[self _processImage:image forEntity:entity imageTable:imageTable completionBlocks:completionBlocks];
353330
}
354331
}
@@ -388,6 +365,58 @@ - (void)_processImage:(UIImage *)image forEntity:(id <FICEntity>)entity imageTab
388365
}
389366
}
390367

368+
- (NSSet *)formatsToProcessForCompletionBlocks:(NSDictionary *)completionBlocksDictionary entity:(id <FICEntity>)entity {
369+
// At the very least, we must process all formats with pending completion blocks
370+
NSMutableSet *formatsToProcess = [NSMutableSet setWithArray:completionBlocksDictionary.allKeys];
371+
372+
// Get the list of format families included by the formats we have to process
373+
NSMutableSet *families;
374+
for (NSString *formatToProcess in formatsToProcess) {
375+
FICImageTable *imageTable = _imageTables[formatToProcess];
376+
FICImageFormat *imageFormat = imageTable.imageFormat;
377+
NSString *tableFormatFamily = imageFormat.family;
378+
if (tableFormatFamily) {
379+
if (!families) {
380+
families = [NSMutableSet set];
381+
}
382+
[families addObject:tableFormatFamily];
383+
}
384+
}
385+
386+
// The delegate can override the list of families to process
387+
if (_delegateImplementsShouldProcessAllFormatsInFamilyForEntity) {
388+
[families minusSet:[families objectsPassingTest:^BOOL(NSString *familyName, BOOL *stop) {
389+
return ![_delegate imageCache:self shouldProcessAllFormatsInFamily:familyName forEntity:entity];
390+
}]];
391+
}
392+
393+
// Ensure that all formats from all of those families are included in the list
394+
if (families.count) {
395+
for (FICImageTable *table in _imageTables.allValues) {
396+
FICImageFormat *imageFormat = table.imageFormat;
397+
NSString *imageFormatName = imageFormat.name;
398+
// If we're already processing this format, keep looking
399+
if ([formatsToProcess containsObject:imageFormatName]) {
400+
continue;
401+
}
402+
403+
// If this format isn't included in any referenced family, keep looking
404+
if (![families containsObject:imageFormat.family]) {
405+
continue;
406+
}
407+
408+
// If the image already exists, keep going
409+
if ([table entryExistsForEntityUUID:entity.UUID sourceImageUUID:entity.sourceImageUUID]) {
410+
continue;
411+
}
412+
413+
[formatsToProcess addObject:imageFormatName];
414+
}
415+
}
416+
417+
return formatsToProcess;
418+
}
419+
391420
#pragma mark - Checking for Image Existence
392421

393422
- (BOOL)imageExistsForEntity:(id <FICEntity>)entity withFormatName:(NSString *)formatName {

0 commit comments

Comments
 (0)