139 lines
3.5 KiB
Objective-C
139 lines
3.5 KiB
Objective-C
/*
|
|
* This file is part of the DMWebImage package.
|
|
* (c) Dailymotion - Olivier Poitrey <rs@dailymotion.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
#import "DMWebImageView.h"
|
|
#import "DMImageCache.h"
|
|
|
|
static NSOperationQueue *downloadQueue;
|
|
static NSOperationQueue *cacheInQueue;
|
|
|
|
@implementation DMWebImageView
|
|
|
|
- (void)dealloc
|
|
{
|
|
[placeHolderImage release];
|
|
[currentOperation release];
|
|
[super dealloc];
|
|
}
|
|
|
|
#pragma mark RemoteImageView
|
|
|
|
- (void)setImageWithURL:(NSURL *)url
|
|
{
|
|
if (currentOperation != nil)
|
|
{
|
|
[currentOperation cancel]; // remove from queue
|
|
[currentOperation release];
|
|
currentOperation = nil;
|
|
}
|
|
|
|
// Save the placeholder image in order to re-apply it when view is reused
|
|
if (placeHolderImage == nil)
|
|
{
|
|
placeHolderImage = [self.image retain];
|
|
}
|
|
else
|
|
{
|
|
self.image = placeHolderImage;
|
|
}
|
|
|
|
UIImage *cachedImage = [[DMImageCache sharedImageCache] imageFromKey:[url absoluteString]];
|
|
|
|
if (cachedImage)
|
|
{
|
|
self.image = cachedImage;
|
|
}
|
|
else
|
|
{
|
|
if (downloadQueue == nil)
|
|
{
|
|
downloadQueue = [[NSOperationQueue alloc] init];
|
|
[downloadQueue setMaxConcurrentOperationCount:8];
|
|
}
|
|
|
|
currentOperation = [[DMWebImageDownloadOperation alloc] initWithURL:url delegate:self];
|
|
[downloadQueue addOperation:currentOperation];
|
|
}
|
|
}
|
|
|
|
- (void)downloadFinishedWithImage:(UIImage *)anImage
|
|
{
|
|
self.image = anImage;
|
|
[currentOperation release];
|
|
currentOperation = nil;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation DMWebImageDownloadOperation
|
|
|
|
@synthesize url, delegate;
|
|
|
|
- (void)dealloc
|
|
{
|
|
[url release];
|
|
[super dealloc];
|
|
}
|
|
|
|
|
|
- (id)initWithURL:(NSURL *)anUrl delegate:(DMWebImageView *)aDelegate
|
|
{
|
|
if (self = [super init])
|
|
{
|
|
self.url = anUrl;
|
|
self.delegate = aDelegate;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)main
|
|
{
|
|
if (self.isCancelled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
|
|
UIImage *image = [[UIImage alloc] initWithData:data];
|
|
[data release];
|
|
|
|
if (!self.isCancelled)
|
|
{
|
|
[delegate performSelectorOnMainThread:@selector(downloadFinishedWithImage:) withObject:image waitUntilDone:YES];
|
|
}
|
|
|
|
if (cacheInQueue == nil)
|
|
{
|
|
cacheInQueue = [[NSOperationQueue alloc] init];
|
|
[cacheInQueue setMaxConcurrentOperationCount:2];
|
|
}
|
|
|
|
NSString *cacheKey = [url absoluteString];
|
|
|
|
DMImageCache *imageCache = [DMImageCache sharedImageCache];
|
|
|
|
// Store image in memory cache NOW, no need to wait for the cache-in operation queue completion
|
|
[imageCache storeImage:image forKey:cacheKey toDisk:NO];
|
|
|
|
// Perform the cache-in in another operation queue in order to not block a download operation slot
|
|
NSInvocation *cacheInInvocation = [NSInvocation invocationWithMethodSignature:[[imageCache class] instanceMethodSignatureForSelector:@selector(storeImage:forKey:)]];
|
|
[cacheInInvocation setTarget:imageCache];
|
|
[cacheInInvocation setSelector:@selector(storeImage:forKey:)];
|
|
[cacheInInvocation setArgument:&image atIndex:2];
|
|
[cacheInInvocation setArgument:&cacheKey atIndex:3];
|
|
[cacheInInvocation retainArguments];
|
|
NSInvocationOperation *cacheInOperation = [[NSInvocationOperation alloc] initWithInvocation:cacheInInvocation];
|
|
[cacheInQueue addOperation:cacheInOperation];
|
|
[cacheInOperation release];
|
|
|
|
[image release];
|
|
}
|
|
|
|
@end
|