Make SDWebImage ARC friendly by detecting if project is using ARC or not and do the right thing with retain and release

This commit is contained in:
Olivier Poitrey 2012-03-10 17:04:43 +01:00
parent aa6956e9fc
commit 40bcaa1181
8 changed files with 93 additions and 42 deletions

View File

@ -31,7 +31,7 @@ static SDImageCache *instance;
// Init the disk cache // Init the disk cache
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
diskCachePath = [[[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"] retain]; diskCachePath = SDWIReturnRetained([[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"]);
if (![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath]) if (![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath])
{ {
@ -78,13 +78,15 @@ static SDImageCache *instance;
- (void)dealloc - (void)dealloc
{ {
[memCache release], memCache = nil; SDWIRelease(memCache);
[diskCachePath release], diskCachePath = nil; SDWIRelease(diskCachePath);
[cacheInQueue release], cacheInQueue = nil; SDWIRelease(cacheInQueue);
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
#if ! __has_feature(objc_arc)
[super dealloc]; [super dealloc];
#endif
} }
#pragma mark SDImageCache (class methods) #pragma mark SDImageCache (class methods)
@ -128,7 +130,7 @@ static SDImageCache *instance;
{ {
// If no data representation given, convert the UIImage in JPEG and store it // If no data representation given, convert the UIImage in JPEG and store it
// This trick is more CPU/memory intensive and doesn't preserve alpha channel // This trick is more CPU/memory intensive and doesn't preserve alpha channel
UIImage *image = [[self imageFromKey:key fromDisk:YES] retain]; // be thread safe with no lock UIImage *image = SDWIReturnRetained([self imageFromKey:key fromDisk:YES]); // be thread safe with no lock
if (image) if (image)
{ {
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
@ -138,11 +140,11 @@ static SDImageCache *instance;
NSData* jpegData = [NSBitmapImageRep representationOfImageRepsInArray: representations usingType: NSJPEGFileType properties:nil]; NSData* jpegData = [NSBitmapImageRep representationOfImageRepsInArray: representations usingType: NSJPEGFileType properties:nil];
[fileManager createFileAtPath:[self cachePathForKey:key] contents:jpegData attributes:nil]; [fileManager createFileAtPath:[self cachePathForKey:key] contents:jpegData attributes:nil];
#endif #endif
[image release]; SDWIRelease(image);
} }
} }
[fileManager release]; SDWIRelease(fileManager);
} }
- (void)notifyDelegate:(NSDictionary *)arguments - (void)notifyDelegate:(NSDictionary *)arguments
@ -173,7 +175,7 @@ static SDImageCache *instance;
- (void)queryDiskCacheOperation:(NSDictionary *)arguments - (void)queryDiskCacheOperation:(NSDictionary *)arguments
{ {
NSString *key = [arguments objectForKey:@"key"]; NSString *key = [arguments objectForKey:@"key"];
NSMutableDictionary *mutableArguments = [[arguments mutableCopy] autorelease]; NSMutableDictionary *mutableArguments = SDWIReturnAutoreleased([arguments mutableCopy]);
UIImage *image = SDScaledImageForPath(key, [NSData dataWithContentsOfFile:[self cachePathForKey:key]]); UIImage *image = SDScaledImageForPath(key, [NSData dataWithContentsOfFile:[self cachePathForKey:key]]);
@ -215,9 +217,11 @@ static SDImageCache *instance;
{ {
keyWithData = [NSArray arrayWithObjects:key, nil]; keyWithData = [NSArray arrayWithObjects:key, nil];
} }
[cacheInQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(storeKeyWithDataToDisk:) NSInvocationOperation *operation = SDWIReturnAutoreleased([[NSInvocationOperation alloc] initWithTarget:self
object:keyWithData] autorelease]]; selector:@selector(storeKeyWithDataToDisk:)
object:keyWithData]);
[cacheInQueue addOperation:operation];
} }
} }
@ -293,7 +297,10 @@ static SDImageCache *instance;
{ {
[arguments setObject:info forKey:@"userInfo"]; [arguments setObject:info forKey:@"userInfo"];
} }
[cacheOutQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(queryDiskCacheOperation:) object:arguments] autorelease]]; NSInvocationOperation *operation = SDWIReturnAutoreleased([[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(queryDiskCacheOperation:)
object:arguments]);
[cacheOutQueue addOperation:operation];
} }
- (void)removeImageForKey:(NSString *)key - (void)removeImageForKey:(NSString *)key

View File

@ -281,6 +281,8 @@
53922D7D148C55820056699D /* Debug */ = { 53922D7D148C55820056699D /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CLANG_ENABLE_OBJC_ARC = NO;
CLANG_WARN_OBJCPP_ARC_ABI = NO;
DSTROOT = /tmp/SDWebImage.dst; DSTROOT = /tmp/SDWebImage.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = ""; GCC_PREFIX_HEADER = "";
@ -295,6 +297,8 @@
53922D7E148C55820056699D /* Release */ = { 53922D7E148C55820056699D /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CLANG_ENABLE_OBJC_ARC = NO;
CLANG_WARN_OBJCPP_ARC_ABI = NO;
DSTROOT = /tmp/SDWebImage.dst; DSTROOT = /tmp/SDWebImage.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = ""; GCC_PREFIX_HEADER = "";

View File

@ -21,6 +21,30 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#endif #endif
#if ! __has_feature(objc_arc)
#define SDWIAutorelease(__v) ([__v autorelease]);
#define SDWIReturnAutoreleased SDWIAutorelease
#define SDWIRetain(__v) ([__v retain]);
#define SDWIReturnRetained SDWIRetain
#define SDWIRelease(__v) ([__v release], __v = nil);
#define SDWIWeak
#else
// -fobjc-arc
#define SDWIAutorelease(__v)
#define SDWIReturnAutoreleased(__v) (__v)
#define SDWIRetain(__v)
#define SDWIReturnRetained(__v) (__v)
#define SDWIRelease(__v)
#define SDWIWeak __unsafe_unretained
#endif
NS_INLINE UIImage *SDScaledImageForPath(NSString *path, NSData *imageData) NS_INLINE UIImage *SDScaledImageForPath(NSString *path, NSData *imageData)
{ {
if (!imageData) if (!imageData)
@ -44,9 +68,9 @@ NS_INLINE UIImage *SDScaledImageForPath(NSString *path, NSData *imageData)
} }
UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:UIImageOrientationUp]; UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:UIImageOrientationUp];
[image release]; SDWIRelease(image)
image = scaledImage; image = scaledImage;
} }
return [image autorelease]; return SDWIReturnAutoreleased(image);
} }

View File

@ -22,7 +22,7 @@ static SDWebImageDecoder *sharedInstance;
- (void)notifyDelegateOnMainThreadWithInfo:(NSDictionary *)dict - (void)notifyDelegateOnMainThreadWithInfo:(NSDictionary *)dict
{ {
[dict retain]; SDWIRetain(dict);
NSDictionary *decodeInfo = [dict objectForKey:DECODE_INFO_KEY]; NSDictionary *decodeInfo = [dict objectForKey:DECODE_INFO_KEY];
UIImage *decodedImage = [dict objectForKey:DECOMPRESSED_IMAGE_KEY]; UIImage *decodedImage = [dict objectForKey:DECOMPRESSED_IMAGE_KEY];
@ -30,7 +30,7 @@ static SDWebImageDecoder *sharedInstance;
NSDictionary *userInfo = [decodeInfo objectForKey:USER_INFO_KEY]; NSDictionary *userInfo = [decodeInfo objectForKey:USER_INFO_KEY];
[delegate imageDecoder:self didFinishDecodingImage:decodedImage userInfo:userInfo]; [delegate imageDecoder:self didFinishDecodingImage:decodedImage userInfo:userInfo];
[dict release]; SDWIRelease(dict);
} }
- (void)decodeImageWithInfo:(NSDictionary *)decodeInfo - (void)decodeImageWithInfo:(NSDictionary *)decodeInfo
@ -71,13 +71,16 @@ static SDWebImageDecoder *sharedInstance;
NSOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(decodeImageWithInfo:) object:decodeInfo]; NSOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(decodeImageWithInfo:) object:decodeInfo];
[imageDecodingQueue addOperation:operation]; [imageDecodingQueue addOperation:operation];
[operation release]; SDWIRelease(operation);
} }
- (void)dealloc - (void)dealloc
{ {
[imageDecodingQueue release], imageDecodingQueue = nil; SDWIRelease(imageDecodingQueue);
#if ! __has_feature(objc_arc)
[super dealloc]; [super dealloc];
#endif
} }
+ (SDWebImageDecoder *)sharedImageDecoder + (SDWebImageDecoder *)sharedImageDecoder
@ -118,7 +121,7 @@ static SDWebImageDecoder *sharedInstance;
UIImage *decompressedImage = [[UIImage alloc] initWithCGImage:decompressedImageRef]; UIImage *decompressedImage = [[UIImage alloc] initWithCGImage:decompressedImageRef];
CGImageRelease(decompressedImageRef); CGImageRelease(decompressedImageRef);
return [decompressedImage autorelease]; return SDWIReturnAutoreleased(decompressedImage);
} }
@end @end

View File

@ -17,7 +17,7 @@ extern NSString *const SDWebImageDownloadStopNotification;
{ {
@private @private
NSURL *url; NSURL *url;
id<SDWebImageDownloaderDelegate> delegate; SDWIWeak id<SDWebImageDownloaderDelegate> delegate;
NSURLConnection *connection; NSURLConnection *connection;
NSMutableData *imageData; NSMutableData *imageData;
id userInfo; id userInfo;

View File

@ -52,7 +52,7 @@ NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNot
name:SDWebImageDownloadStopNotification object:nil]; name:SDWebImageDownloadStopNotification object:nil];
} }
SDWebImageDownloader *downloader = [[[SDWebImageDownloader alloc] init] autorelease]; SDWebImageDownloader *downloader = SDWIReturnAutoreleased([[SDWebImageDownloader alloc] init]);
downloader.url = url; downloader.url = url;
downloader.delegate = delegate; downloader.delegate = delegate;
downloader.userInfo = userInfo; downloader.userInfo = userInfo;
@ -70,7 +70,7 @@ NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNot
{ {
// In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests // In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15];
self.connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO] autorelease]; self.connection = SDWIReturnAutoreleased([[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]);
// If not in low priority mode, ensure we aren't blocked by UI manipulations (default runloop mode for NSURLConnection is NSEventTrackingRunLoopMode) // If not in low priority mode, ensure we aren't blocked by UI manipulations (default runloop mode for NSURLConnection is NSEventTrackingRunLoopMode)
if (!lowPriority) if (!lowPriority)
@ -78,7 +78,7 @@ NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNot
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
} }
[connection start]; [connection start];
[request release]; SDWIRelease(request);
if (connection) if (connection)
{ {
@ -132,7 +132,7 @@ NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNot
#else #else
[delegate performSelector:@selector(imageDownloader:didFinishWithImage:) withObject:self withObject:image]; [delegate performSelector:@selector(imageDownloader:didFinishWithImage:) withObject:self withObject:image];
#endif #endif
[image release]; SDWIRelease(image)
} }
} }
@ -163,11 +163,14 @@ NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNot
- (void)dealloc - (void)dealloc
{ {
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
[url release], url = nil; SDWIRelease(url);
[connection release], connection = nil; SDWIRelease(connection);
[imageData release], imageData = nil; SDWIRelease(imageData);
[userInfo release], userInfo = nil; SDWIRelease(userInfo);
#if ! __has_feature(objc_arc)
[super dealloc]; [super dealloc];
#endif
} }

View File

@ -30,13 +30,16 @@ static SDWebImageManager *instance;
- (void)dealloc - (void)dealloc
{ {
[downloadDelegates release], downloadDelegates = nil; SDWIRelease(downloadDelegates);
[downloaders release], downloaders = nil; SDWIRelease(downloaders);
[cacheDelegates release], cacheDelegates = nil; SDWIRelease(cacheDelegates);
[cacheURLs release], cacheURLs = nil; SDWIRelease(cacheURLs);
[downloaderForURL release], downloaderForURL = nil; SDWIRelease(downloaderForURL);
[failedURLs release], failedURLs = nil; SDWIRelease(failedURLs);
#if ! __has_feature(objc_arc)
[super dealloc]; [super dealloc];
#endif
} }
@ -114,7 +117,7 @@ static SDWebImageManager *instance;
while ((idx = [downloadDelegates indexOfObjectIdenticalTo:delegate]) != NSNotFound) while ((idx = [downloadDelegates indexOfObjectIdenticalTo:delegate]) != NSNotFound)
{ {
SDWebImageDownloader *downloader = [[downloaders objectAtIndex:idx] retain]; SDWebImageDownloader *downloader = SDWIReturnRetained([downloaders objectAtIndex:idx]);
[downloadDelegates removeObjectAtIndex:idx]; [downloadDelegates removeObjectAtIndex:idx];
[downloaders removeObjectAtIndex:idx]; [downloaders removeObjectAtIndex:idx];
@ -126,7 +129,7 @@ static SDWebImageManager *instance;
[downloaderForURL removeObjectForKey:downloader.url]; [downloaderForURL removeObjectForKey:downloader.url];
} }
[downloader release]; SDWIRelease(downloader);
} }
} }
@ -206,7 +209,7 @@ static SDWebImageManager *instance;
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithImage:(UIImage *)image - (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithImage:(UIImage *)image
{ {
[downloader retain]; SDWIRetain(downloader);
SDWebImageOptions options = [[downloader.userInfo objectForKey:@"options"] intValue]; SDWebImageOptions options = [[downloader.userInfo objectForKey:@"options"] intValue];
// Notify all the downloadDelegates with this downloader // Notify all the downloadDelegates with this downloader
@ -216,7 +219,9 @@ static SDWebImageManager *instance;
SDWebImageDownloader *aDownloader = [downloaders objectAtIndex:uidx]; SDWebImageDownloader *aDownloader = [downloaders objectAtIndex:uidx];
if (aDownloader == downloader) if (aDownloader == downloader)
{ {
id<SDWebImageManagerDelegate> delegate = [[[downloadDelegates objectAtIndex:uidx] retain] autorelease]; id<SDWebImageManagerDelegate> delegate = [downloadDelegates objectAtIndex:uidx];
SDWIRetain(delegate);
SDWIAutorelease(delegate);
if (image) if (image)
{ {
@ -256,12 +261,12 @@ static SDWebImageManager *instance;
// Release the downloader // Release the downloader
[downloaderForURL removeObjectForKey:downloader.url]; [downloaderForURL removeObjectForKey:downloader.url];
[downloader release]; SDWIRelease(downloader);
} }
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFailWithError:(NSError *)error; - (void)imageDownloader:(SDWebImageDownloader *)downloader didFailWithError:(NSError *)error;
{ {
[downloader retain]; SDWIRetain(downloader);
// Notify all the downloadDelegates with this downloader // Notify all the downloadDelegates with this downloader
for (NSInteger idx = (NSInteger)[downloaders count] - 1; idx >= 0; idx--) for (NSInteger idx = (NSInteger)[downloaders count] - 1; idx >= 0; idx--)
@ -270,7 +275,9 @@ static SDWebImageManager *instance;
SDWebImageDownloader *aDownloader = [downloaders objectAtIndex:uidx]; SDWebImageDownloader *aDownloader = [downloaders objectAtIndex:uidx];
if (aDownloader == downloader) if (aDownloader == downloader)
{ {
id<SDWebImageManagerDelegate> delegate = [[[downloadDelegates objectAtIndex:uidx] retain] autorelease]; id<SDWebImageManagerDelegate> delegate = [downloadDelegates objectAtIndex:uidx];
SDWIRetain(delegate);
SDWIAutorelease(delegate);
if ([delegate respondsToSelector:@selector(webImageManager:didFailWithError:)]) if ([delegate respondsToSelector:@selector(webImageManager:didFailWithError:)])
{ {
@ -284,7 +291,7 @@ static SDWebImageManager *instance;
// Release the downloader // Release the downloader
[downloaderForURL removeObjectForKey:downloader.url]; [downloaderForURL removeObjectForKey:downloader.url];
[downloader release]; SDWIRelease(downloader);
} }
@end @end

View File

@ -106,7 +106,10 @@ static SDWebImagePrefetcher *instance;
- (void)dealloc - (void)dealloc
{ {
self.prefetchURLs = nil; self.prefetchURLs = nil;
#if ! __has_feature(objc_arc)
[super dealloc]; [super dealloc];
#endif
} }
@end @end