@@ -325,42 +325,45 @@ - (UIImage *)newImageForEntityUUID:(NSString *)entityUUID sourceImageUUID:(NSStr
325325 BOOL entityUUIDIsCorrect = entityUUID == nil || [entityUUID isEqualToString: entryEntityUUID];
326326 BOOL sourceImageUUIDIsCorrect = sourceImageUUID == nil || [sourceImageUUID isEqualToString: entrySourceImageUUID];
327327
328- if (entityUUIDIsCorrect == NO || sourceImageUUIDIsCorrect == NO ) {
329- // The UUIDs don't match, so we need to invalidate the entry.
330- [self deleteEntryForEntityUUID: entityUUID];
331- [self saveMetadata ];
332- } else {
333- [self _entryWasAccessedWithEntityUUID: entityUUID];
334-
335- // Create CGImageRef whose backing store *is* the mapped image table entry. We avoid a memcpy this way.
336- CGDataProviderRef dataProvider = CGDataProviderCreateWithData ((__bridge_retained void *)entryData, [entryData bytes ], [entryData imageLength ], _FICReleaseImageData);
337-
338- [_inUseEntries addObject: entityUUID];
339- __weak FICImageTable *weakSelf = self;
340- [entryData executeBlockOnDealloc: ^{
341- [weakSelf removeInUseForEntityUUID: entityUUID];
342- }];
343-
344- CGSize pixelSize = [_imageFormat pixelSize ];
345- CGBitmapInfo bitmapInfo = [_imageFormat bitmapInfo ];
346- NSInteger bitsPerComponent = [_imageFormat bitsPerComponent ];
347- NSInteger bitsPerPixel = [_imageFormat bytesPerPixel ] * 8 ;
348- CGColorSpaceRef colorSpace = [_imageFormat isGrayscale ] ? CGColorSpaceCreateDeviceGray () : CGColorSpaceCreateDeviceRGB ();
349-
350- CGImageRef imageRef = CGImageCreate (pixelSize.width , pixelSize.height , bitsPerComponent, bitsPerPixel, _imageRowLength, colorSpace, bitmapInfo, dataProvider, NULL , false , (CGColorRenderingIntent)0 );
351- CGDataProviderRelease (dataProvider);
352- CGColorSpaceRelease (colorSpace);
353-
354- if (imageRef != NULL ) {
355- image = [[UIImage alloc ] initWithCGImage: imageRef scale: _screenScale orientation: UIImageOrientationUp];
356- CGImageRelease (imageRef);
328+ NSNumber *indexNumber = [self _numberForEntryAtIndex: [entryData index ]];
329+ @synchronized (indexNumber) {
330+ if (entityUUIDIsCorrect == NO || sourceImageUUIDIsCorrect == NO ) {
331+ // The UUIDs don't match, so we need to invalidate the entry.
332+ [self deleteEntryForEntityUUID: entityUUID];
333+ [self saveMetadata ];
357334 } else {
358- NSString *message = [NSString stringWithFormat: @" *** FIC Error: %s could not create a new CGImageRef for entity UUID %@ ." , __PRETTY_FUNCTION__, entityUUID];
359- [[FICImageCache sharedImageCache ] _logMessage: message];
360- }
361-
362- if (image != nil && preheatData) {
363- [entryData preheat ];
335+ [self _entryWasAccessedWithEntityUUID: entityUUID];
336+
337+ // Create CGImageRef whose backing store *is* the mapped image table entry. We avoid a memcpy this way.
338+ CGDataProviderRef dataProvider = CGDataProviderCreateWithData ((__bridge_retained void *)entryData, [entryData bytes ], [entryData imageLength ], _FICReleaseImageData);
339+
340+ [_inUseEntries addObject: entityUUID];
341+ __weak FICImageTable *weakSelf = self;
342+ [entryData executeBlockOnDealloc: ^{
343+ [weakSelf removeInUseForEntityUUID: entityUUID];
344+ }];
345+
346+ CGSize pixelSize = [_imageFormat pixelSize ];
347+ CGBitmapInfo bitmapInfo = [_imageFormat bitmapInfo ];
348+ NSInteger bitsPerComponent = [_imageFormat bitsPerComponent ];
349+ NSInteger bitsPerPixel = [_imageFormat bytesPerPixel ] * 8 ;
350+ CGColorSpaceRef colorSpace = [_imageFormat isGrayscale ] ? CGColorSpaceCreateDeviceGray () : CGColorSpaceCreateDeviceRGB ();
351+
352+ CGImageRef imageRef = CGImageCreate (pixelSize.width , pixelSize.height , bitsPerComponent, bitsPerPixel, _imageRowLength, colorSpace, bitmapInfo, dataProvider, NULL , false , (CGColorRenderingIntent)0 );
353+ CGDataProviderRelease (dataProvider);
354+ CGColorSpaceRelease (colorSpace);
355+
356+ if (imageRef != NULL ) {
357+ image = [[UIImage alloc ] initWithCGImage: imageRef scale: _screenScale orientation: UIImageOrientationUp];
358+ CGImageRelease (imageRef);
359+ } else {
360+ NSString *message = [NSString stringWithFormat: @" *** FIC Error: %s could not create a new CGImageRef for entity UUID %@ ." , __PRETTY_FUNCTION__, entityUUID];
361+ [[FICImageCache sharedImageCache ] _logMessage: message];
362+ }
363+
364+ if (image != nil && preheatData) {
365+ [entryData preheat ];
366+ }
364367 }
365368 }
366369 }
@@ -470,6 +473,7 @@ - (FICImageTableEntry *)_entryDataAtIndex:(NSInteger)index {
470473 void *mappedChunkAddress = [chunk bytes ];
471474 void *mappedEntryAddress = mappedChunkAddress + entryOffsetInChunk;
472475 entryData = [[FICImageTableEntry alloc ] initWithImageTableChunk: chunk bytes: mappedEntryAddress length: _entryLength];
476+ [entryData setIndex: index];
473477
474478 [_chunkSet addObject: chunk];
475479
0 commit comments