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

View File

@ -18,6 +18,9 @@
@end
@implementation SDImageCodersManager
{
NSMutableArray<id<SDImageCoder>> *_imageCoders;
}
+ (nonnull instancetype)sharedManager {
static dispatch_once_t once;
@ -31,12 +34,30 @@
- (instancetype)init {
if (self = [super init]) {
// 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);
}
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
- (void)addCoder:(nonnull id<SDImageCoder>)coder {
@ -44,12 +65,7 @@
return;
}
SD_LOCK(self.codersLock);
NSMutableArray<id<SDImageCoder>> *mutableCoders = [self.coders mutableCopy];
if (!mutableCoders) {
mutableCoders = [NSMutableArray array];
}
[mutableCoders addObject:coder];
self.coders = [mutableCoders copy];
[_imageCoders addObject:coder];
SD_UNLOCK(self.codersLock);
}
@ -58,17 +74,13 @@
return;
}
SD_LOCK(self.codersLock);
NSMutableArray<id<SDImageCoder>> *mutableCoders = [self.coders mutableCopy];
[mutableCoders removeObject:coder];
self.coders = [mutableCoders copy];
[_imageCoders removeObject:coder];
SD_UNLOCK(self.codersLock);
}
#pragma mark - SDImageCoder
- (BOOL)canDecodeFromData:(NSData *)data {
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders;
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canDecodeFromData:data]) {
return YES;
@ -78,9 +90,7 @@
}
- (BOOL)canEncodeToFormat:(SDImageFormat)format {
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders;
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canEncodeToFormat:format]) {
return YES;
@ -94,9 +104,7 @@
return nil;
}
UIImage *image;
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders;
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canDecodeFromData:data]) {
image = [coder decodedImageWithData:data options:options];
@ -111,9 +119,7 @@
if (!image) {
return nil;
}
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders;
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canEncodeToFormat:format]) {
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
*/
@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.

View File

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