Add KVO for maxConcurrentDownloads to allow dynamic change

This commit is contained in:
DreamPiggy 2018-03-31 15:51:46 +08:00
parent 47aa73a436
commit 6e402ce41c
3 changed files with 36 additions and 18 deletions

View File

@ -110,7 +110,8 @@ typedef SDHTTPHeadersDictionary * _Nullable (^SDWebImageDownloaderHeadersFilterB
@interface SDWebImageDownloader : NSObject
/**
Downloader Config object - storing all kind of settings
* Downloader Config object - storing all kind of settings.
* Most config properties support dynamic changes during download, except something like `sessionConfiguration`, see `SDWebImageDownloaderConfig` for more detail.
*/
@property (nonatomic, copy, readonly, nonnull) SDWebImageDownloaderConfig *config;

View File

@ -10,6 +10,8 @@
#import "SDWebImageDownloaderConfig.h"
#import "SDWebImageDownloaderOperation.h"
static void * SDWebImageDownloaderContext = &SDWebImageDownloaderContext;
#define LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#define UNLOCK(lock) dispatch_semaphore_signal(lock);
@ -82,8 +84,9 @@
config = SDWebImageDownloaderConfig.defaultDownloaderConfig;
}
_config = [config copy];
[_config addObserver:self forKeyPath:NSStringFromSelector(@selector(maxConcurrentDownloads)) options:0 context:SDWebImageDownloaderContext];
_downloadQueue = [NSOperationQueue new];
_downloadQueue.maxConcurrentOperationCount = 6;
_downloadQueue.maxConcurrentOperationCount = _config.maxConcurrentDownloads;
_downloadQueue.name = @"com.hackemist.SDWebImageDownloader";
_URLOperations = [NSMutableDictionary new];
#ifdef SD_WEBP
@ -97,7 +100,6 @@
if (!sessionConfiguration) {
sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
}
sessionConfiguration.timeoutIntervalForRequest = _config.downloadTimeout;
/**
* Create the session for this task
* We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate
@ -110,6 +112,14 @@
return self;
}
- (void)dealloc {
[self.session invalidateAndCancel];
self.session = nil;
[self.downloadQueue cancelAllOperations];
[self.config removeObserver:self forKeyPath:NSStringFromSelector(@selector(maxConcurrentDownloads)) context:SDWebImageDownloaderContext];
}
- (void)invalidateSessionAndCancel:(BOOL)cancelPendingOperations {
if (self == [SDWebImageDownloader sharedDownloader]) {
return;
@ -121,17 +131,6 @@
}
}
- (void)dealloc {
[self.session invalidateAndCancel];
self.session = nil;
[self.downloadQueue cancelAllOperations];
}
- (NSURLSessionConfiguration *)sessionConfiguration {
return self.session.configuration;
}
- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field {
LOCK(self.headersLock);
if (value) {
@ -279,6 +278,12 @@
return token;
}
- (void)cancelAllDownloads {
[self.downloadQueue cancelAllOperations];
}
#pragma mark - Properties
- (BOOL)isSuspended {
return self.downloadQueue.isSuspended;
}
@ -291,8 +296,20 @@
return self.downloadQueue.operationCount;
}
- (void)cancelAllDownloads {
[self.downloadQueue cancelAllOperations];
- (NSURLSessionConfiguration *)sessionConfiguration {
return self.session.configuration;
}
#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if (context == SDWebImageDownloaderContext) {
if ([keyPath isEqualToString:NSStringFromSelector(@selector(maxConcurrentDownloads))]) {
self.downloadQueue.maxConcurrentOperationCount = self.config.maxConcurrentDownloads;
}
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
#pragma mark Helper methods

View File

@ -42,7 +42,7 @@ typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
@property (nonatomic, assign) NSInteger maxConcurrentDownloads;
/**
* The timeout value (in seconds) for the download operation.
* The timeout value (in seconds) for each download operation.
* Defaults to 15.0.
*/
@property (nonatomic, assign) NSTimeInterval downloadTimeout;
@ -50,7 +50,7 @@ typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
/**
* The custom session configuration in use by NSURLSession. If you don't provide one, we will use `defaultSessionConfiguration` instead.
* Defatuls to nil.
* @note The `timeoutIntervalForRequest` will be override by `downloadTimeout` config.
* @note This property does not support dynamic changes, means it's immutable after the downloader instance initialized.
*/
@property (nonatomic, strong, nullable) NSURLSessionConfiguration *sessionConfiguration;