Merge branch 'master' of https://github.com/rs/SDWebImage into 5.x

# Conflicts:
#	SDWebImage/SDWebImageCodersManager.m
This commit is contained in:
DreamPiggy 2018-04-19 17:04:23 +08:00
commit 31b3726439
2 changed files with 43 additions and 31 deletions

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, strong, readwrite, nullable) NSArray<id<SDWebImageCoder>> *coders; @property (nonatomic, copy, readwrite, nullable) NSArray<id<SDWebImageCoder>> *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

@ -17,10 +17,12 @@
#import "UIImage+WebCache.h" #import "UIImage+WebCache.h"
#import "SDWebImageDefine.h" #import "SDWebImageDefine.h"
#define LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#define UNLOCK(lock) dispatch_semaphore_signal(lock);
@interface SDWebImageCodersManager () @interface SDWebImageCodersManager ()
@property (strong, nonatomic, nonnull) NSMutableArray<SDWebImageCoder>* mutableCoders; @property (nonatomic, strong, nonnull) dispatch_semaphore_t codersLock;
@property (strong, nonatomic, nullable) dispatch_queue_t mutableCodersAccessQueue;
@end @end
@ -38,11 +40,12 @@
- (instancetype)init { - (instancetype)init {
if (self = [super init]) { if (self = [super init]) {
// initialize with default coders // initialize with default coders
_mutableCoders = [@[[SDWebImageImageIOCoder sharedCoder], [SDWebImageGIFCoder sharedCoder], [SDWebImageAPNGCoder sharedCoder]] mutableCopy]; NSMutableArray<id<SDWebImageCoder>> *mutableCoders = [@[[SDWebImageImageIOCoder sharedCoder], [SDWebImageGIFCoder sharedCoder], [SDWebImageAPNGCoder sharedCoder]] mutableCopy];
#ifdef SD_WEBP #ifdef SD_WEBP
[_mutableCoders addObject:[SDWebImageWebPCoder sharedCoder]]; [mutableCoders addObject:[SDWebImageWebPCoder sharedCoder]];
#endif #endif
_mutableCodersAccessQueue = dispatch_queue_create("com.hackemist.SDWebImageCodersManager", DISPATCH_QUEUE_CONCURRENT); _coders = [mutableCoders copy];
_codersLock = dispatch_semaphore_create(1);
} }
return self; return self;
} }
@ -50,36 +53,36 @@
#pragma mark - Coder IO operations #pragma mark - Coder IO operations
- (void)addCoder:(nonnull id<SDWebImageCoder>)coder { - (void)addCoder:(nonnull id<SDWebImageCoder>)coder {
if ([coder conformsToProtocol:@protocol(SDWebImageCoder)]) { if (![coder conformsToProtocol:@protocol(SDWebImageCoder)]) {
dispatch_barrier_sync(self.mutableCodersAccessQueue, ^{ return;
[self.mutableCoders addObject:coder];
});
} }
LOCK(self.codersLock);
NSMutableArray<id<SDWebImageCoder>> *mutableCoders = [self.coders mutableCopy];
if (!mutableCoders) {
mutableCoders = [NSMutableArray array];
}
[mutableCoders addObject:coder];
self.coders = [mutableCoders copy];
UNLOCK(self.codersLock);
} }
- (void)removeCoder:(nonnull id<SDWebImageCoder>)coder { - (void)removeCoder:(nonnull id<SDWebImageCoder>)coder {
dispatch_barrier_sync(self.mutableCodersAccessQueue, ^{ if (![coder conformsToProtocol:@protocol(SDWebImageCoder)]) {
[self.mutableCoders removeObject:coder]; return;
});
} }
LOCK(self.codersLock);
- (NSArray<id<SDWebImageCoder>> *)coders { NSMutableArray<id<SDWebImageCoder>> *mutableCoders = [self.coders mutableCopy];
__block NSArray<id<SDWebImageCoder>> *sortedCoders = nil; [mutableCoders removeObject:coder];
dispatch_sync(self.mutableCodersAccessQueue, ^{ self.coders = [mutableCoders copy];
sortedCoders = (NSArray<id<SDWebImageCoder>> *)[[[self.mutableCoders copy] reverseObjectEnumerator] allObjects]; UNLOCK(self.codersLock);
});
return sortedCoders;
}
- (void)setCoders:(NSArray<id<SDWebImageCoder>> *)coders {
dispatch_barrier_sync(self.mutableCodersAccessQueue, ^{
self.mutableCoders = [coders mutableCopy];
});
} }
#pragma mark - SDWebImageCoder #pragma mark - SDWebImageCoder
- (BOOL)canDecodeFromData:(NSData *)data { - (BOOL)canDecodeFromData:(NSData *)data {
for (id<SDWebImageCoder> coder in self.coders) { LOCK(self.codersLock);
NSArray<id<SDWebImageCoder>> *coders = self.coders;
UNLOCK(self.codersLock);
for (id<SDWebImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canDecodeFromData:data]) { if ([coder canDecodeFromData:data]) {
return YES; return YES;
} }
@ -88,7 +91,10 @@
} }
- (BOOL)canEncodeToFormat:(SDImageFormat)format { - (BOOL)canEncodeToFormat:(SDImageFormat)format {
for (id<SDWebImageCoder> coder in self.coders) { LOCK(self.codersLock);
NSArray<id<SDWebImageCoder>> *coders = self.coders;
UNLOCK(self.codersLock);
for (id<SDWebImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canEncodeToFormat:format]) { if ([coder canEncodeToFormat:format]) {
return YES; return YES;
} }
@ -101,7 +107,10 @@
return nil; return nil;
} }
UIImage *image; UIImage *image;
for (id<SDWebImageCoder> coder in self.coders) { LOCK(self.codersLock);
NSArray<id<SDWebImageCoder>> *coders = self.coders;
UNLOCK(self.codersLock);
for (id<SDWebImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canDecodeFromData:data]) { if ([coder canDecodeFromData:data]) {
image = [coder decodedImageWithData:data options:options]; image = [coder decodedImageWithData:data options:options];
break; break;
@ -115,7 +124,10 @@
if (!image) { if (!image) {
return nil; return nil;
} }
for (id<SDWebImageCoder> coder in self.coders) { LOCK(self.codersLock);
NSArray<id<SDWebImageCoder>> *coders = self.coders;
UNLOCK(self.codersLock);
for (id<SDWebImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canEncodeToFormat:format]) { if ([coder canEncodeToFormat:format]) {
return [coder encodedDataWithImage:image format:format options:nil]; return [coder encodedDataWithImage:image format:format options:nil];
} }