Merge pull request #2660 from dreampiggy/bugfix_caches_manager_lock

Fix the thread safe issue of caches manager and specify the default caches array value.
This commit is contained in:
DreamPiggy 2019-03-31 18:34:44 +08:00 committed by GitHub
commit cc13b18c21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 43 additions and 28 deletions

View File

@ -19,7 +19,7 @@ typedef NS_ENUM(NSUInteger, SDImageCachesManagerOperationPolicy) {
@interface SDImageCachesManager : NSObject <SDImageCache>
/**
Returns the global shared caches manager instance.
Returns the global shared caches manager instance. By default we will set [`SDImageCache.sharedImageCache`] into the caches array.
*/
@property (nonatomic, class, readonly, nonnull) SDImageCachesManager *sharedManager;
@ -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 (atomic, copy, readwrite, nullable) NSArray<id<SDImageCache>> *caches;
@property (nonatomic, copy, readwrite, nullable) NSArray<id<SDImageCache>> *caches;
/**
Add a new cache to the end of caches array. Which has the highest priority.

View File

@ -8,6 +8,13 @@
#import "SDImageCachesManager.h"
#import "SDImageCachesManagerOperation.h"
#import "SDImageCache.h"
@interface SDImageCachesManager ()
@property (nonatomic, strong, nonnull) dispatch_semaphore_t cachesLock;
@end
@implementation SDImageCachesManager
@ -28,6 +35,9 @@
self.removeOperationPolicy = SDImageCachesManagerOperationPolicyConcurrent;
self.containsOperationPolicy = SDImageCachesManagerOperationPolicySerial;
self.clearOperationPolicy = SDImageCachesManagerOperationPolicyConcurrent;
// initialize with default image caches
_caches = @[[SDImageCache sharedImageCache]];
_cachesLock = dispatch_semaphore_create(1);
}
return self;
}
@ -38,21 +48,25 @@
if (![cache conformsToProtocol:@protocol(SDImageCache)]) {
return;
}
SD_LOCK(self.cachesLock);
NSMutableArray<id<SDImageCache>> *mutableCaches = [self.caches mutableCopy];
if (!mutableCaches) {
mutableCaches = [NSMutableArray array];
}
[mutableCaches addObject:cache];
self.caches = [mutableCaches copy];
SD_UNLOCK(self.cachesLock);
}
- (void)removeCache:(id<SDImageCache>)cache {
if (![cache conformsToProtocol:@protocol(SDImageCache)]) {
return;
}
SD_LOCK(self.cachesLock);
NSMutableArray<id<SDImageCache>> *mutableCaches = [self.caches mutableCopy];
[mutableCaches removeObject:cache];
self.caches = [mutableCaches copy];
SD_UNLOCK(self.cachesLock);
}
#pragma mark - SDImageCache
@ -61,7 +75,9 @@
if (!key) {
return nil;
}
NSArray<id<SDImageCache>> *caches = [self.caches copy];
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = self.caches;
SD_UNLOCK(self.cachesLock);
NSUInteger count = caches.count;
if (count == 0) {
return nil;
@ -103,7 +119,9 @@
if (!key) {
return;
}
NSArray<id<SDImageCache>> *caches = [self.caches copy];
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = self.caches;
SD_UNLOCK(self.cachesLock);
NSUInteger count = caches.count;
if (count == 0) {
return;
@ -141,7 +159,9 @@
if (!key) {
return;
}
NSArray<id<SDImageCache>> *caches = [self.caches copy];
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = self.caches;
SD_UNLOCK(self.cachesLock);
NSUInteger count = caches.count;
if (count == 0) {
return;
@ -179,7 +199,9 @@
if (!key) {
return;
}
NSArray<id<SDImageCache>> *caches = [self.caches copy];
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = self.caches;
SD_UNLOCK(self.cachesLock);
NSUInteger count = caches.count;
if (count == 0) {
return;
@ -216,7 +238,9 @@
}
- (void)clearWithCacheType:(SDImageCacheType)cacheType completion:(SDWebImageNoParamsBlock)completionBlock {
NSArray<id<SDImageCache>> *caches = [self.caches copy];
SD_LOCK(self.cachesLock);
NSArray<id<SDImageCache>> *caches = self.caches;
SD_UNLOCK(self.cachesLock);
NSUInteger count = caches.count;
if (count == 0) {
return;

View File

@ -17,10 +17,10 @@
Note: the `coders` getter will return the coders in their reversed order
Example:
- by default we internally set coders = `IOCoder`, `GIFCoder`
- calling `coders` will return `@[IOCoder, GIFCoder]`
- by default we internally set coders = `IOCoder`, `GIFCoder`, `APNGCoder`
- calling `coders` will return `@[IOCoder, GIFCoder, APNGCoder]`
- call `[addCoder:[MyCrazyCoder new]]`
- calling `coders` now returns `@[IOCoder, GIFCoder, MyCrazyCoder]`
- calling `coders` now returns `@[IOCoder, GIFCoder, APNGCoder, MyCrazyCoder]`
Coders
------

View File

@ -31,8 +31,7 @@
- (instancetype)init {
if (self = [super init]) {
// initialize with default coders
NSMutableArray<id<SDImageCoder>> *mutableCoders = [@[[SDImageIOCoder sharedCoder], [SDImageGIFCoder sharedCoder], [SDImageAPNGCoder sharedCoder]] mutableCopy];
_coders = [mutableCoders copy];
_coders = @[[SDImageIOCoder sharedCoder], [SDImageGIFCoder sharedCoder], [SDImageAPNGCoder sharedCoder]];
_codersLock = dispatch_semaphore_create(1);
}
return self;

View File

@ -10,6 +10,9 @@
@interface SDImageLoadersManager : NSObject <SDImageLoader>
/**
Returns the global shared loaders manager instance. By default we will set [`SDWebImageDownloader.sharedDownloader`] into the loaders array.
*/
@property (nonatomic, class, readonly, nonnull) SDImageLoadersManager *sharedManager;
/**

View File

@ -30,8 +30,8 @@
self = [super init];
if (self) {
// initialize with default image loaders
self.loaders = @[[SDWebImageDownloader sharedDownloader]];
self.loadersLock = dispatch_semaphore_create(1);
_loaders = @[[SDWebImageDownloader sharedDownloader]];
_loadersLock = dispatch_semaphore_create(1);
}
return self;
}

View File

@ -27,14 +27,6 @@ static NSString *kTestImageKeyPNG = @"TestImageKey.png";
@implementation SDImageCacheTests
+ (void)setUp {
[[SDImageCachesManager sharedManager] addCache:[SDImageCache sharedImageCache]];
}
+ (void)tearDown {
[[SDImageCachesManager sharedManager] removeCache:[SDImageCache sharedImageCache]];
}
- (void)test01SharedImageCache {
expect([SDImageCache sharedImageCache]).toNot.beNil();
}
@ -452,8 +444,7 @@ static NSString *kTestImageKeyPNG = @"TestImageKey.png";
SDImageCachesManager *cachesManager = [[SDImageCachesManager alloc] init];
SDImageCache *cache1 = [[SDImageCache alloc] initWithNamespace:@"cache1"];
SDImageCache *cache2 = [[SDImageCache alloc] initWithNamespace:@"cache2"];
[cachesManager addCache:cache1];
[cachesManager addCache:cache2];
cachesManager.caches = @[cache1, cache2];
[[NSFileManager defaultManager] removeItemAtPath:cache1.diskCachePath error:nil];
[[NSFileManager defaultManager] removeItemAtPath:cache2.diskCachePath error:nil];
@ -502,8 +493,7 @@ static NSString *kTestImageKeyPNG = @"TestImageKey.png";
SDImageCachesManager *cachesManager = [[SDImageCachesManager alloc] init];
SDImageCache *cache1 = [[SDImageCache alloc] initWithNamespace:@"cache1"];
SDImageCache *cache2 = [[SDImageCache alloc] initWithNamespace:@"cache2"];
[cachesManager addCache:cache1];
[cachesManager addCache:cache2];
cachesManager.caches = @[cache1, cache2];
[[NSFileManager defaultManager] removeItemAtPath:cache1.diskCachePath error:nil];
[[NSFileManager defaultManager] removeItemAtPath:cache2.diskCachePath error:nil];
@ -543,8 +533,7 @@ static NSString *kTestImageKeyPNG = @"TestImageKey.png";
SDImageCachesManager *cachesManager = [[SDImageCachesManager alloc] init];
SDImageCache *cache1 = [[SDImageCache alloc] initWithNamespace:@"cache1"];
SDImageCache *cache2 = [[SDImageCache alloc] initWithNamespace:@"cache2"];
[cachesManager addCache:cache1];
[cachesManager addCache:cache2];
cachesManager.caches = @[cache1, cache2];
[[NSFileManager defaultManager] removeItemAtPath:cache1.diskCachePath error:nil];
[[NSFileManager defaultManager] removeItemAtPath:cache2.diskCachePath error:nil];