diff --git a/SDWebImageDownloader.h b/SDWebImageDownloader.h index 0534406a..fe20bc03 100644 --- a/SDWebImageDownloader.h +++ b/SDWebImageDownloader.h @@ -21,13 +21,16 @@ extern NSString *const SDWebImageDownloadStopNotification; NSURLConnection *connection; NSMutableData *imageData; id userInfo; + BOOL lowPriority; } @property (nonatomic, retain) NSURL *url; @property (nonatomic, assign) id delegate; @property (nonatomic, retain) NSMutableData *imageData; @property (nonatomic, retain) id userInfo; +@property (nonatomic, readwrite) BOOL lowPriority; ++ (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate userInfo:(id)userInfo lowPriority:(BOOL)lowPriority; + (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate userInfo:(id)userInfo; + (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate; - (void)start; diff --git a/SDWebImageDownloader.m b/SDWebImageDownloader.m index d2d2d414..4762a96a 100644 --- a/SDWebImageDownloader.m +++ b/SDWebImageDownloader.m @@ -16,7 +16,7 @@ NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNot @end @implementation SDWebImageDownloader -@synthesize url, delegate, connection, imageData, userInfo; +@synthesize url, delegate, connection, imageData, userInfo, lowPriority; #pragma mark Public Methods @@ -28,6 +28,11 @@ NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNot + (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate userInfo:(id)userInfo { + return [[self class] downloaderWithURL:url delegate:delegate userInfo:userInfo lowPriority:NO]; +} + ++ (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate userInfo:(id)userInfo lowPriority:(BOOL)lowPriority +{ // Bind SDNetworkActivityIndicator if available (download it here: http://github.com/rs/SDNetworkActivityIndicator ) // To use it, just add #import "SDNetworkActivityIndicator.h" in addition to the SDWebImage import if (NSClassFromString(@"SDNetworkActivityIndicator")) @@ -40,11 +45,12 @@ NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNot selector:NSSelectorFromString(@"stopActivity") name:SDWebImageDownloadStopNotification object:nil]; } - + SDWebImageDownloader *downloader = [[[SDWebImageDownloader alloc] init] autorelease]; downloader.url = url; downloader.delegate = delegate; downloader.userInfo = userInfo; + downloader.lowPriority = lowPriority; [downloader performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:YES]; return downloader; } @@ -59,8 +65,12 @@ NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNot // 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]; self.connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO] autorelease]; - // Ensure we aren't blocked by UI manipulations (default runloop mode for NSURLConnection is NSEventTrackingRunLoopMode) - [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + + // If not in low priority mode, ensure we aren't blocked by UI manipulations (default runloop mode for NSURLConnection is NSEventTrackingRunLoopMode) + if (!lowPriority) + { + [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + } [connection start]; [request release]; @@ -106,7 +116,7 @@ NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNot { [delegate performSelector:@selector(imageDownloaderDidFinish:) withObject:self]; } - + if ([delegate respondsToSelector:@selector(imageDownloader:didFinishWithImage:)]) { UIImage *image = [[UIImage alloc] initWithData:imageData]; diff --git a/SDWebImageManager.h b/SDWebImageManager.h index 96809fac..40b7be9a 100644 --- a/SDWebImageManager.h +++ b/SDWebImageManager.h @@ -23,6 +23,7 @@ - (UIImage *)imageWithURL:(NSURL *)url; - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate; - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate retryFailed:(BOOL)retryFailed; +- (void)downloadWithURL:(NSURL *)url delegate:(id)delegate retryFailed:(BOOL)retryFailed lowPriority:(BOOL)lowPriority; - (void)cancelForDelegate:(id)delegate; @end diff --git a/SDWebImageManager.m b/SDWebImageManager.m index c2c0b71a..7384b325 100644 --- a/SDWebImageManager.m +++ b/SDWebImageManager.m @@ -60,15 +60,20 @@ static SDWebImageManager *instance; } - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate retryFailed:(BOOL)retryFailed +{ + [self downloadWithURL:url delegate:delegate retryFailed:retryFailed lowPriority:NO]; +} + +- (void)downloadWithURL:(NSURL *)url delegate:(id)delegate retryFailed:(BOOL)retryFailed lowPriority:(BOOL)lowPriority { if (!url || !delegate || (!retryFailed && [failedURLs containsObject:url])) { return; } - + // Check the on-disk cache async so we don't block the main thread - NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:delegate, @"delegate", url, @"url", nil]; - [[SDImageCache sharedImageCache] queryDiskCacheForKey:[url absoluteString] delegate:self userInfo:info]; + NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:delegate, @"delegate", url, @"url", [NSNumber numberWithBool:lowPriority], @"low_priority", nil]; + [[SDImageCache sharedImageCache] queryDiskCacheForKey:[url absoluteString] delegate:self userInfo:info]; } - (void)cancelForDelegate:(id)delegate @@ -110,16 +115,21 @@ static SDWebImageManager *instance; { NSURL *url = [info objectForKey:@"url"]; id delegate = [info objectForKey:@"delegate"]; + BOOL lowPriority = [[info objectForKey:@"low_priority"] boolValue]; // Share the same downloader for identical URLs so we don't download the same URL several times SDWebImageDownloader *downloader = [downloaderForURL objectForKey:url]; if (!downloader) { - downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self]; + downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self userInfo:nil lowPriority:lowPriority]; [downloaderForURL setObject:downloader forKey:url]; } - + + // If we get a normal priority request, make sure to change type since downloader is shared + if (!lowPriority && downloader.lowPriority) + downloader.lowPriority = NO; + [delegates addObject:delegate]; [downloaders addObject:downloader]; }