Skip to content

Commit 5b06118

Browse files
committed
Declare an entry in use for the remainder of its lifetime after it is used
with CGDataProviderCreateWithData.
1 parent 8ab84a3 commit 5b06118

3 files changed

Lines changed: 33 additions & 8 deletions

File tree

FastImageCache/FICImageTable.m

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -320,15 +320,21 @@ - (UIImage *)newImageForEntityUUID:(NSString *)entityUUID sourceImageUUID:(NSStr
320320
[self saveMetadata];
321321
} else {
322322
[self _entryWasAccessedWithEntityUUID:entityUUID];
323-
323+
324324
// Create CGImageRef whose backing store *is* the mapped image table entry. We avoid a memcpy this way.
325325
CGDataProviderRef dataProvider = CGDataProviderCreateWithData((__bridge_retained void *)entryData, [entryData bytes], [entryData imageLength], _FICReleaseImageData);
326-
326+
327+
[_inUseEntries addObject:entityUUID];
328+
__weak FICImageTable *weakSelf = self;
329+
[entryData executeBlockOnDealloc:^{
330+
[weakSelf removeInUseForEntityUUID:entityUUID];
331+
}];
332+
327333
CGSize pixelSize = [_imageFormat pixelSize];
328334
CGBitmapInfo bitmapInfo = [_imageFormat bitmapInfo];
329335
NSInteger bitsPerComponent = [_imageFormat bitsPerComponent];
330336
NSInteger bitsPerPixel = [_imageFormat bytesPerPixel] * 8;
331-
CGColorSpaceRef colorSpace = [_imageFormat isGrayscale] ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
337+
CGColorSpaceRef colorSpace = [_imageFormat isGrayscale] ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
332338

333339
CGImageRef imageRef = CGImageCreate(pixelSize.width, pixelSize.height, bitsPerComponent, bitsPerPixel, _imageRowLength, colorSpace, bitmapInfo, dataProvider, NULL, false, (CGColorRenderingIntent)0);
334340
CGDataProviderRelease(dataProvider);
@@ -354,6 +360,12 @@ static void _FICReleaseImageData(void *info, const void *data, size_t size) {
354360
CFRelease(info);
355361
}
356362

363+
- (void)removeInUseForEntityUUID:(NSString *)entityUUID {
364+
[_lock lock];
365+
[_inUseEntries removeObject:entityUUID];
366+
[_lock unlock];
367+
}
368+
357369
- (void)deleteEntryForEntityUUID:(NSString *)entityUUID {
358370
if (entityUUID != nil) {
359371
[_lock lock];
@@ -440,7 +452,7 @@ - (FICImageTableEntry *)_entryDataAtIndex:(NSInteger)index {
440452
off_t entryOffsetInChunk = entryOffset - chunkOffset;
441453
void *mappedChunkAddress = [chunk bytes];
442454
void *mappedEntryAddress = mappedChunkAddress + entryOffsetInChunk;
443-
entryData = [[FICImageTableEntry alloc] initWithImageTableChunk:chunk bytes:mappedEntryAddress length:_entryLength];
455+
entryData = [[FICImageTableEntry alloc] initWithImageTableChunk:chunk bytes:mappedEntryAddress length:_entryLength ];
444456
}
445457
}
446458

@@ -464,15 +476,15 @@ - (NSInteger)_nextEntryIndex {
464476
NSString *oldestEvictableEntityUUID = [self oldestEvictableEntityUUID];
465477
if (oldestEvictableEntityUUID) {
466478
[self deleteEntryForEntityUUID:oldestEvictableEntityUUID];
467-
index = [self _nextEntryIndex];
468-
}
479+
index = [self _nextEntryIndex];
480+
}
469481
}
470482

471483
if (index >= [self _maximumCount]) {
472484
NSString *message = [NSString stringWithFormat:@"FICImageTable - unable to evict entry from table '%@' to make room. New index %d, desired max %d", [_imageFormat name], index, [self _maximumCount]];
473485
[[FICImageCache sharedImageCache] _logMessage:message];
474486
}
475-
487+
476488
return index;
477489
}
478490

FastImageCache/FICImageTableEntry.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ typedef struct {
6969
*/
7070
- (instancetype)initWithImageTableChunk:(FICImageTableChunk *)imageTableChunk bytes:(void *)bytes length:(size_t)length;
7171

72+
- (void)executeBlockOnDealloc:(dispatch_block_t)block;
73+
7274
///--------------------------------------------
7375
/// @name Flushing a Modified Image Table Entry
7476
///--------------------------------------------

FastImageCache/FICImageTableEntry.m

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ @interface FICImageTableEntry () {
2121
FICImageTableChunk *_imageTableChunk;
2222
void *_bytes;
2323
size_t _length;
24+
dispatch_block_t _deallocBlock;
2425
}
2526

2627
@end
@@ -64,10 +65,20 @@ - (id)initWithImageTableChunk:(FICImageTableChunk *)imageTableChunk bytes:(void
6465
_bytes = bytes;
6566
_length = length;
6667
}
67-
68+
6869
return self;
6970
}
7071

72+
- (void)executeBlockOnDealloc:(dispatch_block_t)block {
73+
_deallocBlock = [block copy];
74+
}
75+
76+
- (void)dealloc {
77+
if (_deallocBlock) {
78+
_deallocBlock();
79+
}
80+
}
81+
7182
#pragma mark - Other Accessors
7283

7384
+ (NSInteger)metadataVersion {

0 commit comments

Comments
 (0)