Skip to content

Commit 209ec52

Browse files
author
Michael Potter
committed
Use ARC
- Fix various memory leaks - Remove unnecessary code because of ARC - Update README
1 parent 8d7d53d commit 209ec52

21 files changed

+78
-215
lines changed

FastImageCache/FICImageCache.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ typedef void (^FICImageRequestCompletionBlock)(UIImage *sourceImage);
3434
@discussion The delegate is responsible for asynchronously providing the source image for an entity. Optionally, the delegate can require that all formats in a format
3535
family for a particular entity be processed. Any errors that occur in the image cache are also communicated back to the delegate.
3636
*/
37-
@property(nonatomic, assign) id <FICImageCacheDelegate> delegate;
37+
@property (nonatomic, weak) id <FICImageCacheDelegate> delegate;
3838

3939
///---------------------------------------
4040
/// @name Accessing the Shared Image Cache

FastImageCache/FICImageCache.m

+4-19
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ @interface FICImageCache () {
2626
NSMutableDictionary *_formats;
2727
NSMutableDictionary *_imageTables;
2828
NSMutableDictionary *_requests;
29-
id <FICImageCacheDelegate> _delegate;
29+
__weak id <FICImageCacheDelegate> _delegate;
3030

3131
BOOL _delegateImplementsShouldProcessAllFormatsInFamilyForEntity;
3232
BOOL _delegateImplementsErrorDidOccurWithMessage;
@@ -83,14 +83,6 @@ - (id)init {
8383
return self;
8484
}
8585

86-
- (void)dealloc {
87-
[_formats release];
88-
[_imageTables release];
89-
[_requests release];
90-
91-
[super dealloc];
92-
}
93-
9486
#pragma mark - Working with Formats
9587

9688
- (void)setFormats:(NSArray *)formats {
@@ -106,7 +98,6 @@ - (void)setFormats:(NSArray *)formats {
10698
// Only initialize an image table for this format if it is needed on the current device.
10799
FICImageTable *imageTable = [[FICImageTable alloc] initWithFormat:imageFormat];
108100
[_imageTables setObject:imageTable forKey:formatName];
109-
[imageTable release];
110101
[_formats setObject:imageFormat forKey:formatName];
111102

112103
[imageTableFiles addObject:[[imageTable tableFilePath] lastPathComponent]];
@@ -144,7 +135,7 @@ - (NSArray *)formatsWithFamily:(NSString *)family {
144135
}
145136
}
146137

147-
return [[formats copy] autorelease];
138+
return [formats copy];
148139
}
149140

150141
#pragma mark - Retrieving Images
@@ -175,8 +166,6 @@ - (BOOL)_retrieveImageForEntity:(id <FICEntity>)entity withFormatName:(NSString
175166
completionBlock(entity, formatName, image);
176167
});
177168
}
178-
179-
[image release]; // Already retained by the block
180169
});
181170
} else {
182171
UIImage *image = [imageTable newImageForEntityUUID:entityUUID sourceImageUUID:sourceImageUUID];
@@ -192,8 +181,6 @@ - (BOOL)_retrieveImageForEntity:(id <FICEntity>)entity withFormatName:(NSString
192181
});
193182
}
194183
}
195-
196-
[image release]; // Already retained by the block
197184
};
198185

199186
if (image == nil && _delegate != nil) {
@@ -274,7 +261,7 @@ static void _FICAddCompletionBlockForEntity(NSString *formatName, NSMutableDicti
274261
[completionBlocks setObject:blocksArray forKey:formatName];
275262
}
276263

277-
FICImageCacheCompletionBlock completionBlockCopy = [[completionBlock copy] autorelease];
264+
FICImageCacheCompletionBlock completionBlockCopy = [completionBlock copy];
278265
[blocksArray addObject:completionBlockCopy];
279266
}
280267
}
@@ -286,7 +273,7 @@ - (void)setImage:(UIImage *)image forEntity:(id <FICEntity>)entity withFormatNam
286273
NSDictionary *completionBlocksDictionary = nil;
287274

288275
if (completionBlock != nil) {
289-
completionBlocksDictionary = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:[[completionBlock copy] autorelease]] forKey:formatName];
276+
completionBlocksDictionary = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:[completionBlock copy]] forKey:formatName];
290277
}
291278

292279
NSString *entityUUID = [entity UUID];
@@ -360,8 +347,6 @@ - (void)_processImage:(UIImage *)image forEntity:(id <FICEntity>)entity imageTab
360347
}
361348
});
362349
}
363-
364-
[resultImage release];
365350
});
366351
}
367352
}

FastImageCache/FICImageFormat.m

+1-8
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ - (void)setImageSize:(CGSize)imageSize {
6161
#pragma mark - Object Lifecycle
6262

6363
+ (instancetype)formatWithName:(NSString *)name family:(NSString *)family imageSize:(CGSize)imageSize isOpaque:(BOOL)isOpaque maximumCount:(NSInteger)maximumCount devices:(FICImageFormatDevices)devices {
64-
FICImageFormat *imageFormat = [[[FICImageFormat alloc] init] autorelease];
64+
FICImageFormat *imageFormat = [[FICImageFormat alloc] init];
6565

6666
[imageFormat setName:name];
6767
[imageFormat setFamily:family];
@@ -73,13 +73,6 @@ + (instancetype)formatWithName:(NSString *)name family:(NSString *)family imageS
7373
return imageFormat;
7474
}
7575

76-
- (void)dealloc {
77-
[_name release];
78-
[_family release];
79-
80-
[super dealloc];
81-
}
82-
8376
#pragma mark - Working with Dictionary Representations
8477

8578
- (NSDictionary *)dictionaryRepresentation {

FastImageCache/FICImageTable.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ extern NSString *const FICImageTableScreenScaleKey;
4242
/**
4343
The image format that describes the image table.
4444
*/
45-
@property (nonatomic, retain, readonly) FICImageFormat *imageFormat;
45+
@property (nonatomic, strong, readonly) FICImageFormat *imageFormat;
4646

4747
///-----------------------------------------------
4848
/// @name Accessing Information about Image Tables

FastImageCache/FICImageTable.m

+18-55
Original file line numberDiff line numberDiff line change
@@ -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

388355
static 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

FastImageCache/FICImageTableChunk.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@
4242

4343
/**
4444
Initializes a new image table chunk.
45-
46-
@param imageTable The image table to create a chunk from.
4745
4846
@param fileDescriptor The image table's file descriptor to map from.
4947
@@ -53,6 +51,6 @@
5351
5452
@return A new image table chunk.
5553
*/
56-
- (instancetype)initWithImageTable:(FICImageTable *)imageTable fileDescriptor:(int)fileDescriptor index:(NSInteger)index length:(size_t)length;
54+
- (instancetype)initWithFileDescriptor:(int)fileDescriptor index:(NSInteger)index length:(size_t)length;
5755

5856
@end

0 commit comments

Comments
 (0)