@@ -49,7 +49,7 @@ @interface FICImageTable () {
4949 size_t _chunkLength;
5050 NSInteger _chunkCount;
5151
52- CFMutableDictionaryRef _chunkDictionary ;
52+ NSMapTable *_chunkMapTable ;
5353 NSMutableArray *_recentChunks;
5454 NSRecursiveLock *_lock;
5555
@@ -104,9 +104,9 @@ + (NSString *)directoryPath {
104104 static dispatch_once_t onceToken;
105105 dispatch_once (&onceToken, ^{
106106 NSArray *paths = NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES );
107- __directoryPath = [[[ paths objectAtIndex: 0 ] stringByAppendingPathComponent: @" ImageTables" ] retain ];
107+ __directoryPath = [[paths objectAtIndex: 0 ] stringByAppendingPathComponent: @" ImageTables" ];
108108
109- NSFileManager *fileManager = [[[ NSFileManager alloc ] init ] autorelease ];
109+ NSFileManager *fileManager = [[NSFileManager alloc ] init ];
110110 BOOL directoryExists = [fileManager fileExistsAtPath: __directoryPath];
111111 if (directoryExists == NO ) {
112112 [fileManager createDirectoryAtPath: __directoryPath withIntermediateDirectories: YES attributes: nil error: nil ];
@@ -128,15 +128,15 @@ - (instancetype)initWithFormat:(FICImageFormat *)imageFormat {
128128
129129 _lock = [[NSRecursiveLock alloc ] init ];
130130 _imageFormat = [imageFormat copy ];
131- _imageFormatDictionary = [[ imageFormat dictionaryRepresentation ] retain ];
131+ _imageFormatDictionary = [imageFormat dictionaryRepresentation ];
132132
133133 _screenScale = [[UIScreen mainScreen ] scale ];
134134
135135 int bytesPerPixel = 4 ;
136136 _imageRowLength = FICByteAlignForCoreAnimation ([_imageFormat pixelSize ].width * bytesPerPixel);
137137 _imageLength = _imageRowLength * (NSInteger )[_imageFormat pixelSize ].height ;
138138
139- _chunkDictionary = CFDictionaryCreateMutable ( kCFAllocatorDefault , 0 , NULL , NULL ); // Non-retained keys and values
139+ _chunkMapTable = [ NSMapTable mapTableWithKeyOptions: NSMapTableStrongMemory valueOptions: NSMapTableWeakMemory ];
140140
141141 _indexMap = [[NSMutableDictionary alloc ] init ];
142142 _occupiedIndexes = [[NSMutableIndexSet alloc ] init ];
@@ -176,8 +176,7 @@ - (instancetype)initWithFormat:(FICImageFormat *)imageFormat {
176176 // If something goes wrong and we can't open the image table file, then we have no choice but to release and nil self.
177177 NSString *message = [NSString stringWithFormat: @" *** FIC Error: %s could not open the image table file at path %@ . The image table was not created." , __PRETTY_FUNCTION__, _filePath];
178178 [[FICImageCache sharedImageCache ] _logMessage: message];
179-
180- [self release ];
179+
181180 self = nil ;
182181 }
183182 }
@@ -190,54 +189,32 @@ - (instancetype)init {
190189}
191190
192191- (void )dealloc {
193- [_imageFormat release ];
194- [_filePath release ];
195-
196- CFRelease (_chunkDictionary);
197-
198- [_indexMap release ];
199- [_occupiedIndexes release ];
200- [_MRUEntries release ];
201- [_sourceImageMap release ];
202- [_imageFormatDictionary release ];
203- [_recentChunks release ];
204-
205192 if (_fileDescriptor >= 0 ) {
206193 close (_fileDescriptor);
207194 }
208-
209- [_lock release ];
210-
211- [super dealloc ];
212195}
213196
214197#pragma mark - Working with Chunks
215198
216199- (FICImageTableChunk *)_cachedChunkAtIndex : (NSInteger )index {
217- return (FICImageTableChunk *)CFDictionaryGetValue (_chunkDictionary, (const void *)index);
200+ FICImageTableChunk *cachedChunk = [_chunkMapTable objectForKey: @(index)];
201+
202+ return cachedChunk;
218203}
219204
220205- (void )_setChunk : (FICImageTableChunk *)chunk index : (NSInteger )index {
221206 if (chunk != nil ) {
222- CFDictionarySetValue (_chunkDictionary, ( const void *)index, ( const void *)chunk) ;
207+ [_chunkMapTable setObject: chunk forKey: @(index)] ;
223208 } else {
224- CFDictionaryRemoveValue (_chunkDictionary, ( const void *) index);
209+ [_chunkMapTable removeObjectForKey: @( index)] ;
225210 }
226211}
227212
228- - (void )_cleanupRecentChunks {
229- [_lock lock ];
230-
231- [_recentChunks removeAllObjects ];
232-
233- [_lock unlock ];
234- }
235-
236213- (FICImageTableChunk *)_chunkAtIndex : (NSInteger )index {
237214 FICImageTableChunk *chunk = nil ;
238215
239216 if (index < _chunkCount) {
240- chunk = [[ self _cachedChunkAtIndex: index] retain ];
217+ chunk = [self _cachedChunkAtIndex: index];
241218
242219 if (chunk == nil ) {
243220 size_t chunkLength = _chunkLength;
@@ -246,7 +223,7 @@ - (FICImageTableChunk *)_chunkAtIndex:(NSInteger)index {
246223 chunkLength = _fileLength - chunkOffset;
247224 }
248225
249- chunk = [[FICImageTableChunk alloc ] initWithImageTable: self fileDescriptor : _fileDescriptor index: index length: chunkLength];
226+ chunk = [[FICImageTableChunk alloc ] initWithFileDescriptor : _fileDescriptor index: index length: chunkLength];
250227 [self _setChunk: chunk index: index];
251228 }
252229
@@ -260,15 +237,7 @@ - (FICImageTableChunk *)_chunkAtIndex:(NSInteger)index {
260237 }
261238 }
262239
263- return [chunk autorelease ];
264- }
265-
266- - (void )_chunkWillBeDeallocated : (FICImageTableChunk *)chunk {
267- [_lock lock ];
268-
269- [self _setChunk: nil index: [chunk index ]];
270-
271- [_lock unlock ];
240+ return chunk;
272241}
273242
274243#pragma mark - Storing, Retrieving, and Deleting Entries
@@ -351,11 +320,9 @@ - (UIImage *)newImageForEntityUUID:(NSString *)entityUUID sourceImageUUID:(NSStr
351320 } else {
352321 [self _entryWasAccessedWithEntityUUID: entityUUID];
353322
354- [entryData retain ]; // Released by _FICReleaseImageData
355-
356323 // Create CGImageRef whose backing store *is* the mapped image table entry. We avoid a memcpy this way.
357324 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB ();
358- CGDataProviderRef dataProvider = CGDataProviderCreateWithData ((void *)entryData, [entryData bytes ], [entryData imageLength ], _FICReleaseImageData);
325+ CGDataProviderRef dataProvider = CGDataProviderCreateWithData ((__bridge_retained void *)entryData, [entryData bytes ], [entryData imageLength ], _FICReleaseImageData);
359326
360327 CGSize pixelSize = [_imageFormat pixelSize ];
361328 CGBitmapInfo bitmapInfo;
@@ -386,8 +353,7 @@ - (UIImage *)newImageForEntityUUID:(NSString *)entityUUID sourceImageUUID:(NSStr
386353}
387354
388355static void _FICReleaseImageData (void *info, const void *data, size_t size) {
389- FICImageTableEntry *entryData = (FICImageTableEntry *)info;
390- [entryData release ];
356+ CFRelease (info);
391357}
392358
393359- (void )deleteEntryForEntityUUID : (NSString *)entityUUID {
@@ -452,7 +418,7 @@ - (void)_setEntryCount:(NSInteger)entryCount {
452418 } else {
453419 _fileLength = fileLength;
454420 _entryCount = entryCount;
455- _chunkCount = ( _entryCount + _entriesPerChunk - 1 ) / _entriesPerChunk;
421+ _chunkCount = _entriesPerChunk > 0 ? (( _entryCount + _entriesPerChunk - 1 ) / _entriesPerChunk) : 0 ;
456422 }
457423 }
458424}
@@ -478,7 +444,7 @@ - (FICImageTableEntry *)_entryDataAtIndex:(NSInteger)index {
478444
479445 [_lock unlock ];
480446
481- return [ entryData autorelease ] ;
447+ return entryData;
482448}
483449
484450- (NSInteger )_nextEntryIndex {
@@ -489,7 +455,6 @@ - (NSInteger)_nextEntryIndex {
489455 if (index == NSNotFound ) {
490456 index = _entryCount;
491457 }
492- [unoccupiedIndexes release ];
493458
494459 if (index >= [_imageFormat maximumCount ] && [_MRUEntries count ]) {
495460 // Evict the oldest/least-recently accessed entry here
@@ -533,10 +498,8 @@ - (void)_entryWasAccessedWithEntityUUID:(NSString *)entityUUID {
533498 if (index == NSNotFound ) {
534499 [_MRUEntries insertObject: entityUUID atIndex: 0 ];
535500 } else if (index != 0 ) {
536- [entityUUID retain ];
537501 [_MRUEntries removeObjectAtIndex: index];
538502 [_MRUEntries insertObject: entityUUID atIndex: 0 ];
539- [entityUUID release ];
540503 }
541504}
542505
0 commit comments