Merge pull request #2667 from zhongwuzw/guarantee_thread_safe

Guarantee thread-safe for SDImageCachesManager SDImageCodersManager SDImageLoadersManager
This commit is contained in:
DreamPiggy 2019-04-01 17:44:22 +08:00 committed by GitHub
commit b0f1006e3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 71 additions and 55 deletions

View File

@ -58,7 +58,7 @@ typedef NS_ENUM(NSUInteger, SDImageCachesManagerOperationPolicy) {
/**
All caches in caches manager. The caches array is a priority queue, which means the later added cache will have the highest priority
*/
@property (nonatomic, copy, readwrite, nullable) NSArray<id<SDImageCache>> *caches;
@property (nonatomic, copy, nullable) NSArray<id<SDImageCache>> *caches;
/**
Add a new cache to the end of caches array. Which has the highest priority.

View File

@ -17,6 +17,9 @@
@end
@implementation SDImageCachesManager
{
NSMutableArray<id<SDImageCache>> *_imageCaches;
}
+ (SDImageCachesManager *)sharedManager {
static dispatch_once_t onceToken;
@ -36,12 +39,28 @@
self.containsOperationPolicy = SDImageCachesManagerOperationPolicySerial;
self.clearOperationPolicy = SDImageCachesManagerOperationPolicyConcurrent;
// initialize with default image caches
_caches = @[[SDImageCache sharedImageCache]];
_imageCaches = [NSMutableArray arrayWithObject:[SDImageCache sharedImageCache]];
_cachesLock = dispatch_semaphore_create(1);
}
return self;
}
- (NSArray<id<SDImageCache>> *)caches {
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = [_imageCaches copy];
SD_UNLOCK(self.cachesLock);
return caches;
}
- (void)setCaches:(NSArray<id<SDImageCache>> *)caches {
SD_LOCK(self.cachesLock);
[_imageCaches removeAllObjects];
if (caches.count) {
[_imageCaches addObjectsFromArray:caches];
}
SD_UNLOCK(self.cachesLock);
}
#pragma mark - Cache IO operations
- (void)addCache:(id<SDImageCache>)cache {
@ -49,12 +68,7 @@
return;
}
SD_LOCK(self.cachesLock);
NSMutableArray<id<SDImageCache>> *mutableCaches = [self.caches mutableCopy];
if (!mutableCaches) {
mutableCaches = [NSMutableArray array];
}
[mutableCaches addObject:cache];
self.caches = [mutableCaches copy];
[_imageCaches addObject:cache];
SD_UNLOCK(self.cachesLock);
}
@ -63,9 +77,7 @@
return;
}
SD_LOCK(self.cachesLock);
NSMutableArray<id<SDImageCache>> *mutableCaches = [self.caches mutableCopy];
[mutableCaches removeObject:cache];
self.caches = [mutableCaches copy];
[_imageCaches removeObject:cache];
SD_UNLOCK(self.cachesLock);
}
@ -75,9 +87,7 @@
if (!key) {
return nil;
}
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = self.caches;
SD_UNLOCK(self.cachesLock);
NSUInteger count = caches.count;
if (count == 0) {
return nil;
@ -119,9 +129,7 @@
if (!key) {
return;
}
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = self.caches;
SD_UNLOCK(self.cachesLock);
NSUInteger count = caches.count;
if (count == 0) {
return;
@ -159,9 +167,7 @@
if (!key) {
return;
}
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = self.caches;
SD_UNLOCK(self.cachesLock);
NSUInteger count = caches.count;
if (count == 0) {
return;
@ -199,9 +205,7 @@
if (!key) {
return;
}
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = self.caches;
SD_UNLOCK(self.cachesLock);
NSUInteger count = caches.count;
if (count == 0) {
return;
@ -238,9 +242,7 @@
}
- (void)clearWithCacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock {
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = self.caches;
SD_UNLOCK(self.cachesLock);
NSUInteger count = caches.count;
if (count == 0) {
return;

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];