@@ -52,7 +52,7 @@ @interface FICImageTable () {
52
52
53
53
NSMutableDictionary *_chunkDictionary;
54
54
NSCountedSet *_chunkSet;
55
-
55
+
56
56
NSRecursiveLock *_lock;
57
57
CFMutableDictionaryRef _indexNumbers;
58
58
@@ -108,9 +108,9 @@ + (NSString *)directoryPath {
108
108
static dispatch_once_t onceToken;
109
109
dispatch_once (&onceToken, ^{
110
110
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES );
111
- __directoryPath = [[paths objectAtIndex: 0 ] stringByAppendingPathComponent: @" ImageTables" ];
111
+ __directoryPath = [[[ paths objectAtIndex: 0 ] stringByAppendingPathComponent: @" ImageTables" ] retain ];
112
112
113
- NSFileManager *fileManager = [[NSFileManager alloc ] init ];
113
+ NSFileManager *fileManager = [[[ NSFileManager alloc ] init ] autorelease ];
114
114
BOOL directoryExists = [fileManager fileExistsAtPath: __directoryPath];
115
115
if (directoryExists == NO ) {
116
116
[fileManager createDirectoryAtPath: __directoryPath withIntermediateDirectories: YES attributes: nil error: nil ];
@@ -134,7 +134,7 @@ - (instancetype)initWithFormat:(FICImageFormat *)imageFormat {
134
134
_indexNumbers = CFDictionaryCreateMutable (kCFAllocatorDefault , 0 , NULL , &kCFTypeDictionaryValueCallBacks );
135
135
136
136
_imageFormat = [imageFormat copy ];
137
- _imageFormatDictionary = [imageFormat dictionaryRepresentation ];
137
+ _imageFormatDictionary = [[ imageFormat dictionaryRepresentation ] retain ];
138
138
139
139
_screenScale = [[UIScreen mainScreen ] scale ];
140
140
@@ -145,12 +145,12 @@ - (instancetype)initWithFormat:(FICImageFormat *)imageFormat {
145
145
146
146
_chunkDictionary = [[NSMutableDictionary alloc ] init ];
147
147
_chunkSet = [[NSCountedSet alloc ] init ];
148
-
148
+
149
149
_indexMap = [[NSMutableDictionary alloc ] init ];
150
150
_occupiedIndexes = [[NSMutableIndexSet alloc ] init ];
151
151
152
152
_MRUEntries = [[NSMutableOrderedSet alloc ] init ];
153
- _inUseEntries = [NSCountedSet set ];
153
+ _inUseEntries = [[ NSCountedSet alloc ] init ];
154
154
155
155
_sourceImageMap = [[NSMutableDictionary alloc ] init ];
156
156
@@ -188,7 +188,8 @@ - (instancetype)initWithFormat:(FICImageFormat *)imageFormat {
188
188
// If something goes wrong and we can't open the image table file, then we have no choice but to release and nil self.
189
189
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];
190
190
[[FICImageCache sharedImageCache ] _logMessage: message];
191
-
191
+
192
+ [self release ];
192
193
self = nil ;
193
194
}
194
195
}
@@ -201,9 +202,24 @@ - (instancetype)init {
201
202
}
202
203
203
204
- (void )dealloc {
205
+ [_imageFormat release ];
206
+ [_filePath release ];
207
+
208
+ [_indexMap release ];
209
+ [_occupiedIndexes release ];
210
+ [_MRUEntries release ];
211
+ [_sourceImageMap release ];
212
+ [_imageFormatDictionary release ];
213
+ [_chunkDictionary release ];
214
+ [_chunkSet release ];
215
+
204
216
if (_fileDescriptor >= 0 ) {
205
217
close (_fileDescriptor);
206
218
}
219
+
220
+ [_lock release ];
221
+
222
+ [super dealloc ];
207
223
}
208
224
209
225
#pragma mark - Working with Chunks
@@ -225,7 +241,7 @@ - (FICImageTableChunk *)_chunkAtIndex:(NSInteger)index {
225
241
FICImageTableChunk *chunk = nil ;
226
242
227
243
if (index < _chunkCount) {
228
- chunk = [self _cachedChunkAtIndex: index ];
244
+ chunk = [[ self _cachedChunkAtIndex: index ] retain ];
229
245
230
246
if (chunk == nil ) {
231
247
size_t chunkLength = _chunkLength;
@@ -234,7 +250,7 @@ - (FICImageTableChunk *)_chunkAtIndex:(NSInteger)index {
234
250
chunkLength = (size_t )(_fileLength - chunkOffset);
235
251
}
236
252
237
- chunk = [[FICImageTableChunk alloc ] initWithFileDescriptor : _fileDescriptor index :index length: chunkLength];
253
+ chunk = [[FICImageTableChunk alloc ] initWithImageTable: self fileDescriptor : _fileDescriptor index :index length: chunkLength];
238
254
[self _setChunk: chunk index :index ];
239
255
}
240
256
}
@@ -244,7 +260,15 @@ - (FICImageTableChunk *)_chunkAtIndex:(NSInteger)index {
244
260
[[FICImageCache sharedImageCache ] _logMessage: message];
245
261
}
246
262
247
- return chunk;
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 ];
248
272
}
249
273
250
274
#pragma mark - Storing, Retrieving, and Deleting Entries
@@ -291,8 +315,6 @@ - (void)setEntryForEntityUUID:(NSString *)entityUUID sourceImageUUID:(NSString *
291
315
[_lock unlock ];
292
316
293
317
CGContextRef context = CGBitmapContextCreate ([entryData bytes ], pixelSize.width , pixelSize.height , bitsPerComponent, _imageRowLength, colorSpace, bitmapInfo);
294
- CGColorSpaceRelease (colorSpace);
295
-
296
318
CGContextTranslateCTM (context, 0 , pixelSize.height );
297
319
CGContextScaleCTM (context, _screenScale, -_screenScale);
298
320
@@ -307,6 +329,7 @@ - (void)setEntryForEntityUUID:(NSString *)entityUUID sourceImageUUID:(NSString *
307
329
} else {
308
330
[_lock unlock ];
309
331
}
332
+ CGColorSpaceRelease (colorSpace);
310
333
} else {
311
334
[_lock unlock ];
312
335
}
@@ -334,13 +357,15 @@ - (UIImage *)newImageForEntityUUID:(NSString *)entityUUID sourceImageUUID:(NSStr
334
357
} else {
335
358
[self _entryWasAccessedWithEntityUUID: entityUUID];
336
359
360
+ [entryData retain ]; // Released by _FICReleaseImageData
361
+
337
362
// 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);
363
+ CGDataProviderRef dataProvider = CGDataProviderCreateWithData ((void *)entryData, [entryData bytes ], [entryData imageLength ], _FICReleaseImageData);
339
364
340
365
[_inUseEntries addObject: entityUUID];
341
- __weak FICImageTable *weakSelf = self;
366
+
342
367
[entryData executeBlockOnDealloc: ^{
343
- [weakSelf removeInUseForEntityUUID: entityUUID];
368
+ [self removeInUseForEntityUUID: entityUUID];
344
369
}];
345
370
346
371
CGSize pixelSize = [_imageFormat pixelSize ];
@@ -442,7 +467,7 @@ - (int)_maximumCount {
442
467
}
443
468
444
469
- (void )_setEntryCount : (NSInteger )entryCount {
445
- if (entryCount != _entryCount) {
470
+ if (entryCount != _entryCount && _entriesPerChunk > 0 ) {
446
471
off_t fileLength = entryCount * _entryLength;
447
472
int result = ftruncate (_fileDescriptor, fileLength);
448
473
@@ -452,7 +477,7 @@ - (void)_setEntryCount:(NSInteger)entryCount {
452
477
} else {
453
478
_fileLength = fileLength;
454
479
_entryCount = entryCount;
455
- _chunkCount = _entriesPerChunk > 0 ? (( _entryCount + _entriesPerChunk - 1 ) / _entriesPerChunk) : 0 ;
480
+ _chunkCount = ( _entryCount + _entriesPerChunk - 1 ) / _entriesPerChunk;
456
481
}
457
482
}
458
483
}
@@ -477,9 +502,8 @@ - (FICImageTableEntry *)_entryDataAtIndex:(NSInteger)index {
477
502
478
503
[_chunkSet addObject: chunk];
479
504
480
- __weak FICImageTable *weakSelf = self;
481
505
[entryData executeBlockOnDealloc: ^{
482
- [weakSelf _entryWasDeallocatedFromChunk: chunk];
506
+ [self _entryWasDeallocatedFromChunk: chunk];
483
507
}];
484
508
}
485
509
}
@@ -491,7 +515,7 @@ - (FICImageTableEntry *)_entryDataAtIndex:(NSInteger)index {
491
515
[[FICImageCache sharedImageCache ] _logMessage: message];
492
516
}
493
517
494
- return entryData;
518
+ return [ entryData autorelease ] ;
495
519
}
496
520
497
521
- (void )_entryWasDeallocatedFromChunk : (FICImageTableChunk *)chunk {
@@ -511,6 +535,7 @@ - (NSInteger)_nextEntryIndex {
511
535
if (index == NSNotFound ) {
512
536
index = _entryCount;
513
537
}
538
+ [unoccupiedIndexes release ];
514
539
515
540
if (index >= [self _maximumCount ] && [_MRUEntries count ]) {
516
541
// Evict the oldest/least-recently accessed entry here
@@ -576,8 +601,10 @@ - (void)_entryWasAccessedWithEntityUUID:(NSString *)entityUUID {
576
601
if (index == NSNotFound ) {
577
602
[_MRUEntries insertObject: entityUUID atIndex: 0 ];
578
603
} else if (index != 0 ) {
604
+ [entityUUID retain ];
579
605
[_MRUEntries removeObjectAtIndex: index ];
580
606
[_MRUEntries insertObject: entityUUID atIndex: 0 ];
607
+ [entityUUID release ];
581
608
}
582
609
}
583
610
@@ -602,6 +629,7 @@ - (void)saveMetadata {
602
629
if (!entryDict) {
603
630
entryDict = [[NSMutableDictionary alloc ] init ];
604
631
[entryMetadata setObject: entryDict forKey: entityUUID];
632
+ [entryDict release ];
605
633
}
606
634
NSNumber *tableIndexVal = [_indexMap objectForKey: entityUUID];
607
635
NSString *contextUUID = [_sourceImageMap objectForKey: entityUUID];
@@ -616,7 +644,7 @@ - (void)saveMetadata {
616
644
617
645
NSDictionary *metadataDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
618
646
entryMetadata, FICImageTableMetadataKey,
619
- [_imageFormatDictionary copy ], FICImageTableFormatKey, nil ];
647
+ [[ _imageFormatDictionary copy ] autorelease ], FICImageTableFormatKey, nil ];
620
648
621
649
[_lock unlock ];
622
650
0 commit comments