Thread-safe for CodersManager and LoadersManager

This commit is contained in:
zhongwuzw 2019-04-01 17:19:11 +08:00
parent aa890c5d9a
commit 60255f5bd2
5 changed files with 55 additions and 41 deletions

View File

@ -18,7 +18,7 @@
@implementation SDImageCachesManager @implementation SDImageCachesManager
{ {
NSMutableArray<id<SDImageCache>> *caches_; NSMutableArray<id<SDImageCache>> *_imageCaches;
} }
+ (SDImageCachesManager *)sharedManager { + (SDImageCachesManager *)sharedManager {
@ -39,7 +39,7 @@
self.containsOperationPolicy = SDImageCachesManagerOperationPolicySerial; self.containsOperationPolicy = SDImageCachesManagerOperationPolicySerial;
self.clearOperationPolicy = SDImageCachesManagerOperationPolicyConcurrent; self.clearOperationPolicy = SDImageCachesManagerOperationPolicyConcurrent;
// initialize with default image caches // initialize with default image caches
caches_ = [NSMutableArray arrayWithObject:[SDImageCache sharedImageCache]]; _imageCaches = [NSMutableArray arrayWithObject:[SDImageCache sharedImageCache]];
_cachesLock = dispatch_semaphore_create(1); _cachesLock = dispatch_semaphore_create(1);
} }
return self; return self;
@ -47,16 +47,16 @@
- (NSArray<id<SDImageCache>> *)caches { - (NSArray<id<SDImageCache>> *)caches {
SD_LOCK(self.cachesLock); SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = [caches_ copy]; NSArray<id<SDImageCache>> *caches = [_imageCaches copy];
SD_UNLOCK(self.cachesLock); SD_UNLOCK(self.cachesLock);
return caches; return caches;
} }
- (void)setCaches:(NSArray<id<SDImageCache>> *)caches { - (void)setCaches:(NSArray<id<SDImageCache>> *)caches {
SD_LOCK(self.cachesLock); SD_LOCK(self.cachesLock);
[caches_ removeAllObjects]; [_imageCaches removeAllObjects];
if (caches.count) { if (caches.count) {
[caches_ addObjectsFromArray:caches]; [_imageCaches addObjectsFromArray:caches];
} }
SD_UNLOCK(self.cachesLock); SD_UNLOCK(self.cachesLock);
} }
@ -68,7 +68,7 @@
return; return;
} }
SD_LOCK(self.cachesLock); SD_LOCK(self.cachesLock);
[caches_ addObject:cache]; [_imageCaches addObject:cache];
SD_UNLOCK(self.cachesLock); SD_UNLOCK(self.cachesLock);
} }
@ -77,7 +77,7 @@
return; return;
} }
SD_LOCK(self.cachesLock); SD_LOCK(self.cachesLock);
[caches_ removeObject:cache]; [_imageCaches removeObject:cache];
SD_UNLOCK(self.cachesLock); SD_UNLOCK(self.cachesLock);
} }

View File

@ -39,7 +39,7 @@
/** /**
All coders in coders manager. The coders array is a priority queue, which means the later added coder will have the highest priority All coders in coders manager. The coders array is a priority queue, which means the later added coder will have the highest priority
*/ */
@property (nonatomic, copy, readwrite, nullable) NSArray<id<SDImageCoder>> *coders; @property (nonatomic, copy, nullable) NSArray<id<SDImageCoder>> *coders;
/** /**
Add a new coder to the end of coders array. Which has the highest priority. Add a new coder to the end of coders array. Which has the highest priority.

View File

@ -18,6 +18,9 @@
@end @end
@implementation SDImageCodersManager @implementation SDImageCodersManager
{
NSMutableArray<id<SDImageCoder>> *_imageCoders;
}
+ (nonnull instancetype)sharedManager { + (nonnull instancetype)sharedManager {
static dispatch_once_t once; static dispatch_once_t once;
@ -31,12 +34,30 @@
- (instancetype)init { - (instancetype)init {
if (self = [super init]) { if (self = [super init]) {
// initialize with default coders // initialize with default coders
_coders = @[[SDImageIOCoder sharedCoder], [SDImageGIFCoder sharedCoder], [SDImageAPNGCoder sharedCoder]]; _imageCoders = [NSMutableArray arrayWithArray:@[[SDImageIOCoder sharedCoder], [SDImageGIFCoder sharedCoder], [SDImageAPNGCoder sharedCoder]]];
_codersLock = dispatch_semaphore_create(1); _codersLock = dispatch_semaphore_create(1);
} }
return self; return self;
} }
- (NSArray<id<SDImageCoder>> *)coders
{
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = [_imageCoders copy];
SD_UNLOCK(self.codersLock);
return coders;
}
- (void)setCoders:(NSArray<id<SDImageCoder>> *)coders
{
SD_LOCK(self.codersLock);
[_imageCoders removeAllObjects];
if (coders.count) {
[_imageCoders addObjectsFromArray:coders];
}
SD_UNLOCK(self.codersLock);
}
#pragma mark - Coder IO operations #pragma mark - Coder IO operations
- (void)addCoder:(nonnull id<SDImageCoder>)coder { - (void)addCoder:(nonnull id<SDImageCoder>)coder {
@ -44,12 +65,7 @@
return; return;
} }
SD_LOCK(self.codersLock); SD_LOCK(self.codersLock);
NSMutableArray<id<SDImageCoder>> *mutableCoders = [self.coders mutableCopy]; [_imageCoders addObject:coder];
if (!mutableCoders) {
mutableCoders = [NSMutableArray array];
}
[mutableCoders addObject:coder];
self.coders = [mutableCoders copy];
SD_UNLOCK(self.codersLock); SD_UNLOCK(self.codersLock);
} }
@ -58,17 +74,13 @@
return; return;
} }
SD_LOCK(self.codersLock); SD_LOCK(self.codersLock);
NSMutableArray<id<SDImageCoder>> *mutableCoders = [self.coders mutableCopy]; [_imageCoders removeObject:coder];
[mutableCoders removeObject:coder];
self.coders = [mutableCoders copy];
SD_UNLOCK(self.codersLock); SD_UNLOCK(self.codersLock);
} }
#pragma mark - SDImageCoder #pragma mark - SDImageCoder
- (BOOL)canDecodeFromData:(NSData *)data { - (BOOL)canDecodeFromData:(NSData *)data {
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders; NSArray<id<SDImageCoder>> *coders = self.coders;
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) { for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canDecodeFromData:data]) { if ([coder canDecodeFromData:data]) {
return YES; return YES;
@ -78,9 +90,7 @@
} }
- (BOOL)canEncodeToFormat:(SDImageFormat)format { - (BOOL)canEncodeToFormat:(SDImageFormat)format {
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders; NSArray<id<SDImageCoder>> *coders = self.coders;
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) { for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canEncodeToFormat:format]) { if ([coder canEncodeToFormat:format]) {
return YES; return YES;
@ -94,9 +104,7 @@
return nil; return nil;
} }
UIImage *image; UIImage *image;
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders; NSArray<id<SDImageCoder>> *coders = self.coders;
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) { for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canDecodeFromData:data]) { if ([coder canDecodeFromData:data]) {
image = [coder decodedImageWithData:data options:options]; image = [coder decodedImageWithData:data options:options];
@ -111,9 +119,7 @@
if (!image) { if (!image) {
return nil; return nil;
} }
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders; NSArray<id<SDImageCoder>> *coders = self.coders;
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) { for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canEncodeToFormat:format]) { if ([coder canEncodeToFormat:format]) {
return [coder encodedDataWithImage:image format:format options:options]; return [coder encodedDataWithImage:image format:format options:options];

View File

@ -18,7 +18,7 @@
/** /**
All image loaders in manager. The loaders array is a priority queue, which means the later added loader will have the highest priority All image loaders in manager. The loaders array is a priority queue, which means the later added loader will have the highest priority
*/ */
@property (nonatomic, copy, readwrite, nullable) NSArray<id<SDImageLoader>>* loaders; @property (nonatomic, copy, nullable) NSArray<id<SDImageLoader>>* loaders;
/** /**
Add a new image loader to the end of loaders array. Which has the highest priority. Add a new image loader to the end of loaders array. Which has the highest priority.

View File

@ -16,6 +16,9 @@
@end @end
@implementation SDImageLoadersManager @implementation SDImageLoadersManager
{
NSMutableArray<id<SDImageLoader>>* _imageLoaders;
}
+ (SDImageLoadersManager *)sharedManager { + (SDImageLoadersManager *)sharedManager {
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
@ -30,12 +33,28 @@
self = [super init]; self = [super init];
if (self) { if (self) {
// initialize with default image loaders // initialize with default image loaders
_loaders = @[[SDWebImageDownloader sharedDownloader]]; _imageLoaders = [NSMutableArray arrayWithObject:[SDWebImageDownloader sharedDownloader]];
_loadersLock = dispatch_semaphore_create(1); _loadersLock = dispatch_semaphore_create(1);
} }
return self; return self;
} }
- (NSArray<id<SDImageLoader>> *)loaders {
SD_LOCK(self.loadersLock);
NSArray<id<SDImageLoader>>* loaders = [_imageLoaders copy];
SD_UNLOCK(self.loadersLock);
return loaders;
}
- (void)setLoaders:(NSArray<id<SDImageLoader>> *)loaders {
SD_LOCK(self.loadersLock);
[_imageLoaders removeAllObjects];
if (loaders.count) {
[_imageLoaders addObjectsFromArray:loaders];
}
SD_UNLOCK(self.loadersLock);
}
#pragma mark - Loader Property #pragma mark - Loader Property
- (void)addLoader:(id<SDImageLoader>)loader { - (void)addLoader:(id<SDImageLoader>)loader {
@ -43,12 +62,7 @@
return; return;
} }
SD_LOCK(self.loadersLock); SD_LOCK(self.loadersLock);
NSMutableArray<id<SDImageLoader>> *mutableLoaders = [self.loaders mutableCopy]; [_imageLoaders addObject:loader];
if (!mutableLoaders) {
mutableLoaders = [NSMutableArray array];
}
[mutableLoaders addObject:loader];
self.loaders = [mutableLoaders copy];
SD_UNLOCK(self.loadersLock); SD_UNLOCK(self.loadersLock);
} }
@ -57,18 +71,14 @@
return; return;
} }
SD_LOCK(self.loadersLock); SD_LOCK(self.loadersLock);
NSMutableArray<id<SDImageLoader>> *mutableLoaders = [self.loaders mutableCopy]; [_imageLoaders removeObject:loader];
[mutableLoaders removeObject:loader];
self.loaders = [mutableLoaders copy];
SD_UNLOCK(self.loadersLock); SD_UNLOCK(self.loadersLock);
} }
#pragma mark - SDImageLoader #pragma mark - SDImageLoader
- (BOOL)canRequestImageForURL:(nullable NSURL *)url { - (BOOL)canRequestImageForURL:(nullable NSURL *)url {
SD_LOCK(self.loadersLock);
NSArray<id<SDImageLoader>> *loaders = self.loaders; NSArray<id<SDImageLoader>> *loaders = self.loaders;
SD_UNLOCK(self.loadersLock);
for (id<SDImageLoader> loader in loaders.reverseObjectEnumerator) { for (id<SDImageLoader> loader in loaders.reverseObjectEnumerator) {
if ([loader canRequestImageForURL:url]) { if ([loader canRequestImageForURL:url]) {
return YES; return YES;
@ -81,9 +91,7 @@
if (!url) { if (!url) {
return nil; return nil;
} }
SD_LOCK(self.loadersLock);
NSArray<id<SDImageLoader>> *loaders = self.loaders; NSArray<id<SDImageLoader>> *loaders = self.loaders;
SD_UNLOCK(self.loadersLock);
for (id<SDImageLoader> loader in loaders.reverseObjectEnumerator) { for (id<SDImageLoader> loader in loaders.reverseObjectEnumerator) {
if ([loader canRequestImageForURL:url]) { if ([loader canRequestImageForURL:url]) {
return [loader requestImageWithURL:url options:options context:context progress:progressBlock completed:completedBlock]; return [loader requestImageWithURL:url options:options context:context progress:progressBlock completed:completedBlock];