DMWebImageView.m 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * This file is part of the DMWebImage package.
  3. * (c) Dailymotion - Olivier Poitrey <rs@dailymotion.com>
  4. *
  5. * For the full copyright and license information, please view the LICENSE
  6. * file that was distributed with this source code.
  7. */
  8. #import "DMWebImageView.h"
  9. #import "DMImageCache.h"
  10. static NSOperationQueue *downloadQueue;
  11. static NSOperationQueue *cacheInQueue;
  12. @implementation DMWebImageView
  13. - (void)dealloc
  14. {
  15. [placeHolderImage release];
  16. [currentOperation release];
  17. [super dealloc];
  18. }
  19. #pragma mark RemoteImageView
  20. - (void)setImageWithURL:(NSURL *)url
  21. {
  22. if (currentOperation != nil)
  23. {
  24. [currentOperation cancel]; // remove from queue
  25. [currentOperation release];
  26. currentOperation = nil;
  27. }
  28. // Save the placeholder image in order to re-apply it when view is reused
  29. if (placeHolderImage == nil)
  30. {
  31. placeHolderImage = [self.image retain];
  32. }
  33. else
  34. {
  35. self.image = placeHolderImage;
  36. }
  37. UIImage *cachedImage = [[DMImageCache sharedImageCache] imageFromKey:[url absoluteString]];
  38. if (cachedImage)
  39. {
  40. self.image = cachedImage;
  41. }
  42. else
  43. {
  44. if (downloadQueue == nil)
  45. {
  46. downloadQueue = [[NSOperationQueue alloc] init];
  47. [downloadQueue setMaxConcurrentOperationCount:8];
  48. }
  49. currentOperation = [[DMWebImageDownloadOperation alloc] initWithURL:url delegate:self];
  50. [downloadQueue addOperation:currentOperation];
  51. }
  52. }
  53. - (void)downloadFinishedWithImage:(UIImage *)anImage
  54. {
  55. self.image = anImage;
  56. [currentOperation release];
  57. currentOperation = nil;
  58. }
  59. @end
  60. @implementation DMWebImageDownloadOperation
  61. @synthesize url, delegate;
  62. - (void)dealloc
  63. {
  64. [url release];
  65. [super dealloc];
  66. }
  67. - (id)initWithURL:(NSURL *)anUrl delegate:(DMWebImageView *)aDelegate
  68. {
  69. if (self = [super init])
  70. {
  71. self.url = anUrl;
  72. self.delegate = aDelegate;
  73. }
  74. return self;
  75. }
  76. - (void)main
  77. {
  78. if (self.isCancelled)
  79. {
  80. return;
  81. }
  82. NSData *data = [[NSData alloc] initWithContentsOfURL:url];
  83. UIImage *image = [[UIImage alloc] initWithData:data];
  84. [data release];
  85. if (!self.isCancelled)
  86. {
  87. [delegate performSelectorOnMainThread:@selector(downloadFinishedWithImage:) withObject:image waitUntilDone:YES];
  88. }
  89. if (cacheInQueue == nil)
  90. {
  91. cacheInQueue = [[NSOperationQueue alloc] init];
  92. [cacheInQueue setMaxConcurrentOperationCount:2];
  93. }
  94. NSString *cacheKey = [url absoluteString];
  95. DMImageCache *imageCache = [DMImageCache sharedImageCache];
  96. // Store image in memory cache NOW, no need to wait for the cache-in operation queue completion
  97. [imageCache storeImage:image forKey:cacheKey toDisk:NO];
  98. // Perform the cache-in in another operation queue in order to not block a download operation slot
  99. NSInvocation *cacheInInvocation = [NSInvocation invocationWithMethodSignature:[[imageCache class] instanceMethodSignatureForSelector:@selector(storeImage:forKey:)]];
  100. [cacheInInvocation setTarget:imageCache];
  101. [cacheInInvocation setSelector:@selector(storeImage:forKey:)];
  102. [cacheInInvocation setArgument:&image atIndex:2];
  103. [cacheInInvocation setArgument:&cacheKey atIndex:3];
  104. [cacheInInvocation retainArguments];
  105. NSInvocationOperation *cacheInOperation = [[NSInvocationOperation alloc] initWithInvocation:cacheInInvocation];
  106. [cacheInQueue addOperation:cacheInOperation];
  107. [cacheInOperation release];
  108. [image release];
  109. }
  110. @end