DMWebImageView.m
3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//
// DMWebImageView.m
// Dailymotion
//
// Created by Olivier Poitrey on 18/09/09.
// Copyright 2009 Dailymotion. All rights reserved.
//
#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