Skip to content

Commit

Permalink
Use ARC
Browse files Browse the repository at this point in the history
- Fix various memory leaks
- Remove unnecessary code because of ARC
- Update README
  • Loading branch information
Michael Potter committed Oct 23, 2013
1 parent 8d7d53d commit 209ec52
Show file tree
Hide file tree
Showing 21 changed files with 78 additions and 215 deletions.
2 changes: 1 addition & 1 deletion FastImageCache/FICImageCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ typedef void (^FICImageRequestCompletionBlock)(UIImage *sourceImage);
@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
family for a particular entity be processed. Any errors that occur in the image cache are also communicated back to the delegate.
*/
@property(nonatomic, assign) id <FICImageCacheDelegate> delegate;
@property (nonatomic, weak) id <FICImageCacheDelegate> delegate;

///---------------------------------------
/// @name Accessing the Shared Image Cache
Expand Down
23 changes: 4 additions & 19 deletions FastImageCache/FICImageCache.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ @interface FICImageCache () {
NSMutableDictionary *_formats;
NSMutableDictionary *_imageTables;
NSMutableDictionary *_requests;
id <FICImageCacheDelegate> _delegate;
__weak id <FICImageCacheDelegate> _delegate;

BOOL _delegateImplementsShouldProcessAllFormatsInFamilyForEntity;
BOOL _delegateImplementsErrorDidOccurWithMessage;
Expand Down Expand Up @@ -83,14 +83,6 @@ - (id)init {
return self;
}

- (void)dealloc {
[_formats release];
[_imageTables release];
[_requests release];

[super dealloc];
}

#pragma mark - Working with Formats

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

[imageTableFiles addObject:[[imageTable tableFilePath] lastPathComponent]];
Expand Down Expand Up @@ -144,7 +135,7 @@ - (NSArray *)formatsWithFamily:(NSString *)family {
}
}

return [[formats copy] autorelease];
return [formats copy];
}

#pragma mark - Retrieving Images
Expand Down Expand Up @@ -175,8 +166,6 @@ - (BOOL)_retrieveImageForEntity:(id <FICEntity>)entity withFormatName:(NSString
completionBlock(entity, formatName, image);
});
}

[image release]; // Already retained by the block
});
} else {
UIImage *image = [imageTable newImageForEntityUUID:entityUUID sourceImageUUID:sourceImageUUID];
Expand All @@ -192,8 +181,6 @@ - (BOOL)_retrieveImageForEntity:(id <FICEntity>)entity withFormatName:(NSString
});
}
}

[image release]; // Already retained by the block
};

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

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

if (completionBlock != nil) {
completionBlocksDictionary = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:[[completionBlock copy] autorelease]] forKey:formatName];
completionBlocksDictionary = [NSDictionary dictionaryWithObject:[NSArray arrayWithObject:[completionBlock copy]] forKey:formatName];
}

NSString *entityUUID = [entity UUID];
Expand Down Expand Up @@ -360,8 +347,6 @@ - (void)_processImage:(UIImage *)image forEntity:(id <FICEntity>)entity imageTab
}
});
}

[resultImage release];
});
}
}
Expand Down
9 changes: 1 addition & 8 deletions FastImageCache/FICImageFormat.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ - (void)setImageSize:(CGSize)imageSize {
#pragma mark - Object Lifecycle

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

[imageFormat setName:name];
[imageFormat setFamily:family];
Expand All @@ -73,13 +73,6 @@ + (instancetype)formatWithName:(NSString *)name family:(NSString *)family imageS
return imageFormat;
}

- (void)dealloc {
[_name release];
[_family release];

[super dealloc];
}

#pragma mark - Working with Dictionary Representations

- (NSDictionary *)dictionaryRepresentation {
Expand Down
2 changes: 1 addition & 1 deletion FastImageCache/FICImageTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ extern NSString *const FICImageTableScreenScaleKey;
/**
The image format that describes the image table.
*/
@property (nonatomic, retain, readonly) FICImageFormat *imageFormat;
@property (nonatomic, strong, readonly) FICImageFormat *imageFormat;

///-----------------------------------------------
/// @name Accessing Information about Image Tables
Expand Down
73 changes: 18 additions & 55 deletions FastImageCache/FICImageTable.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ @interface FICImageTable () {
size_t _chunkLength;
NSInteger _chunkCount;

CFMutableDictionaryRef _chunkDictionary;
NSMapTable *_chunkMapTable;
NSMutableArray *_recentChunks;
NSRecursiveLock *_lock;

Expand Down Expand Up @@ -104,9 +104,9 @@ + (NSString *)directoryPath {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
__directoryPath = [[[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageTables"] retain];
__directoryPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageTables"];

NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
NSFileManager *fileManager = [[NSFileManager alloc] init];
BOOL directoryExists = [fileManager fileExistsAtPath:__directoryPath];
if (directoryExists == NO) {
[fileManager createDirectoryAtPath:__directoryPath withIntermediateDirectories:YES attributes:nil error:nil];
Expand All @@ -128,15 +128,15 @@ - (instancetype)initWithFormat:(FICImageFormat *)imageFormat {

_lock = [[NSRecursiveLock alloc] init];
_imageFormat = [imageFormat copy];
_imageFormatDictionary = [[imageFormat dictionaryRepresentation] retain];
_imageFormatDictionary = [imageFormat dictionaryRepresentation];

_screenScale = [[UIScreen mainScreen] scale];

int bytesPerPixel = 4;
_imageRowLength = FICByteAlignForCoreAnimation([_imageFormat pixelSize].width * bytesPerPixel);
_imageLength = _imageRowLength * (NSInteger)[_imageFormat pixelSize].height;

_chunkDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); // Non-retained keys and values
_chunkMapTable = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory valueOptions:NSMapTableWeakMemory];

_indexMap = [[NSMutableDictionary alloc] init];
_occupiedIndexes = [[NSMutableIndexSet alloc] init];
Expand Down Expand Up @@ -176,8 +176,7 @@ - (instancetype)initWithFormat:(FICImageFormat *)imageFormat {
// If something goes wrong and we can't open the image table file, then we have no choice but to release and nil self.
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];
[[FICImageCache sharedImageCache] _logMessage:message];

[self release];

self = nil;
}
}
Expand All @@ -190,54 +189,32 @@ - (instancetype)init {
}

- (void)dealloc {
[_imageFormat release];
[_filePath release];

CFRelease(_chunkDictionary);

[_indexMap release];
[_occupiedIndexes release];
[_MRUEntries release];
[_sourceImageMap release];
[_imageFormatDictionary release];
[_recentChunks release];

if (_fileDescriptor >= 0) {
close(_fileDescriptor);
}

[_lock release];

[super dealloc];
}

#pragma mark - Working with Chunks

- (FICImageTableChunk *)_cachedChunkAtIndex:(NSInteger)index {
return (FICImageTableChunk *)CFDictionaryGetValue(_chunkDictionary, (const void *)index);
FICImageTableChunk *cachedChunk = [_chunkMapTable objectForKey:@(index)];

return cachedChunk;
}

- (void)_setChunk:(FICImageTableChunk *)chunk index:(NSInteger)index {
if (chunk != nil) {
CFDictionarySetValue(_chunkDictionary, (const void *)index, (const void *)chunk);
[_chunkMapTable setObject:chunk forKey:@(index)];
} else {
CFDictionaryRemoveValue(_chunkDictionary, (const void *)index);
[_chunkMapTable removeObjectForKey:@(index)];
}
}

- (void)_cleanupRecentChunks {
[_lock lock];

[_recentChunks removeAllObjects];

[_lock unlock];
}

- (FICImageTableChunk *)_chunkAtIndex:(NSInteger)index {
FICImageTableChunk *chunk = nil;

if (index < _chunkCount) {
chunk = [[self _cachedChunkAtIndex:index] retain];
chunk = [self _cachedChunkAtIndex:index];

if (chunk == nil) {
size_t chunkLength = _chunkLength;
Expand All @@ -246,7 +223,7 @@ - (FICImageTableChunk *)_chunkAtIndex:(NSInteger)index {
chunkLength = _fileLength - chunkOffset;
}

chunk = [[FICImageTableChunk alloc] initWithImageTable:self fileDescriptor:_fileDescriptor index:index length:chunkLength];
chunk = [[FICImageTableChunk alloc] initWithFileDescriptor:_fileDescriptor index:index length:chunkLength];
[self _setChunk:chunk index:index];
}

Expand All @@ -260,15 +237,7 @@ - (FICImageTableChunk *)_chunkAtIndex:(NSInteger)index {
}
}

return [chunk autorelease];
}

- (void)_chunkWillBeDeallocated:(FICImageTableChunk *)chunk {
[_lock lock];

[self _setChunk:nil index:[chunk index]];

[_lock unlock];
return chunk;
}

#pragma mark - Storing, Retrieving, and Deleting Entries
Expand Down Expand Up @@ -351,11 +320,9 @@ - (UIImage *)newImageForEntityUUID:(NSString *)entityUUID sourceImageUUID:(NSStr
} else {
[self _entryWasAccessedWithEntityUUID:entityUUID];

[entryData retain]; // Released by _FICReleaseImageData

// Create CGImageRef whose backing store *is* the mapped image table entry. We avoid a memcpy this way.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGDataProviderRef dataProvider = CGDataProviderCreateWithData((void *)entryData, [entryData bytes], [entryData imageLength], _FICReleaseImageData);
CGDataProviderRef dataProvider = CGDataProviderCreateWithData((__bridge_retained void *)entryData, [entryData bytes], [entryData imageLength], _FICReleaseImageData);

CGSize pixelSize = [_imageFormat pixelSize];
CGBitmapInfo bitmapInfo;
Expand Down Expand Up @@ -386,8 +353,7 @@ - (UIImage *)newImageForEntityUUID:(NSString *)entityUUID sourceImageUUID:(NSStr
}

static void _FICReleaseImageData(void *info, const void *data, size_t size) {
FICImageTableEntry *entryData = (FICImageTableEntry *)info;
[entryData release];
CFRelease(info);
}

- (void)deleteEntryForEntityUUID:(NSString *)entityUUID {
Expand Down Expand Up @@ -452,7 +418,7 @@ - (void)_setEntryCount:(NSInteger)entryCount {
} else {
_fileLength = fileLength;
_entryCount = entryCount;
_chunkCount = (_entryCount + _entriesPerChunk - 1) / _entriesPerChunk;
_chunkCount = _entriesPerChunk > 0 ? ((_entryCount + _entriesPerChunk - 1) / _entriesPerChunk) : 0;
}
}
}
Expand All @@ -478,7 +444,7 @@ - (FICImageTableEntry *)_entryDataAtIndex:(NSInteger)index {

[_lock unlock];

return [entryData autorelease];
return entryData;
}

- (NSInteger)_nextEntryIndex {
Expand All @@ -489,7 +455,6 @@ - (NSInteger)_nextEntryIndex {
if (index == NSNotFound) {
index = _entryCount;
}
[unoccupiedIndexes release];

if (index >= [_imageFormat maximumCount] && [_MRUEntries count]) {
// Evict the oldest/least-recently accessed entry here
Expand Down Expand Up @@ -533,10 +498,8 @@ - (void)_entryWasAccessedWithEntityUUID:(NSString *)entityUUID {
if (index == NSNotFound) {
[_MRUEntries insertObject:entityUUID atIndex:0];
} else if (index != 0) {
[entityUUID retain];
[_MRUEntries removeObjectAtIndex:index];
[_MRUEntries insertObject:entityUUID atIndex:0];
[entityUUID release];
}
}

Expand Down
4 changes: 1 addition & 3 deletions FastImageCache/FICImageTableChunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@

/**
Initializes a new image table chunk.
@param imageTable The image table to create a chunk from.
@param fileDescriptor The image table's file descriptor to map from.
Expand All @@ -53,6 +51,6 @@
@return A new image table chunk.
*/
- (instancetype)initWithImageTable:(FICImageTable *)imageTable fileDescriptor:(int)fileDescriptor index:(NSInteger)index length:(size_t)length;
- (instancetype)initWithFileDescriptor:(int)fileDescriptor index:(NSInteger)index length:(size_t)length;

@end
Loading

0 comments on commit 209ec52

Please sign in to comment.