Revert "Merge pull request #1898 from walkline/master into 5.x"

This commit is contained in:
DreamPiggy 2018-04-13 16:48:15 +08:00
parent db646df3f1
commit e1d96e7812
5 changed files with 43 additions and 72 deletions

View File

@ -56,8 +56,6 @@ typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache);
typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize);
typedef void(^SDWebImageCompletionWithPossibleErrorBlock)(NSError * _Nullable error);
typedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString * _Nonnull key);
/**
@ -140,7 +138,7 @@ typedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString *
*/
- (void)storeImage:(nullable UIImage *)image
forKey:(nullable NSString *)key
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock;
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
/**
* Asynchronously store an image into memory and disk cache at the given key.
@ -153,7 +151,7 @@ typedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString *
- (void)storeImage:(nullable UIImage *)image
forKey:(nullable NSString *)key
toDisk:(BOOL)toDisk
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock;
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
/**
* Asynchronously store an image into memory and disk cache at the given key.
@ -170,18 +168,16 @@ typedef NSString * _Nullable (^SDImageCacheAdditionalCachePathBlock)(NSString *
imageData:(nullable NSData *)imageData
forKey:(nullable NSString *)key
toDisk:(BOOL)toDisk
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock;
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
/**
* Synchronously store image NSData into disk cache at the given key.
*
* @param imageData The image data to store
* @param key The unique image cache key, usually it's image absolute URL
* @param error NSError pointer, for possible file I/O errors, See FoundationErrors.h
*/
- (BOOL)storeImageDataToDisk:(nullable NSData *)imageData
forKey:(nullable NSString *)key
error:(NSError * _Nullable * _Nullable)error;
- (void)storeImageDataToDisk:(nullable NSData *)imageData
forKey:(nullable NSString *)key;
#pragma mark - Query and Retrieve Ops

View File

@ -252,14 +252,14 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
- (void)storeImage:(nullable UIImage *)image
forKey:(nullable NSString *)key
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock {
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
[self storeImage:image imageData:nil forKey:key toDisk:YES completion:completionBlock];
}
- (void)storeImage:(nullable UIImage *)image
forKey:(nullable NSString *)key
toDisk:(BOOL)toDisk
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock {
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
[self storeImage:image imageData:nil forKey:key toDisk:toDisk completion:completionBlock];
}
@ -267,10 +267,10 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
imageData:(nullable NSData *)imageData
forKey:(nullable NSString *)key
toDisk:(BOOL)toDisk
completion:(nullable SDWebImageCompletionWithPossibleErrorBlock)completionBlock {
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
if (!image || !key) {
if (completionBlock) {
completionBlock(nil);
completionBlock();
}
return;
}
@ -282,7 +282,6 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
if (toDisk) {
dispatch_async(self.ioQueue, ^{
NSError * writeError = nil;
@autoreleasepool {
NSData *data = imageData;
if (!data && image) {
@ -295,50 +294,41 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
}
data = [[SDWebImageCodersManager sharedManager] encodedDataWithImage:image format:format options:nil];
}
[self _storeImageDataToDisk:data forKey:key error:&writeError];
[self _storeImageDataToDisk:data forKey:key];
}
if (completionBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(writeError);
completionBlock();
});
}
});
} else {
if (completionBlock) {
completionBlock(nil);
completionBlock();
}
}
}
- (BOOL)storeImageDataToDisk:(nullable NSData *)imageData
forKey:(nullable NSString *)key
error:(NSError * _Nullable __autoreleasing * _Nullable)error {
- (void)storeImageDataToDisk:(nullable NSData *)imageData
forKey:(nullable NSString *)key {
if (!imageData || !key) {
return NO;
}
__autoreleasing NSError *fileError;
if (!error) {
error = &fileError;
return;
}
__block BOOL success = YES;
void(^storeImageDataBlock)(void) = ^{
success = [self _storeImageDataToDisk:imageData forKey:key error:error];
};
dispatch_sync(self.ioQueue, storeImageDataBlock);
return success;
dispatch_sync(self.ioQueue, ^{
[self _storeImageDataToDisk:imageData forKey:key];
});
}
// Make sure to call form io queue by caller
- (BOOL)_storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key error:(NSError * _Nullable __autoreleasing * _Nonnull)error {
- (void)_storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key {
if (!imageData || !key) {
return NO;
return;
}
if (![self.fileManager fileExistsAtPath:_diskCachePath]) {
if (![self.fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:error]) {
return NO;
if (![self.fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:nil]) {
return;
}
}
@ -349,8 +339,8 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
// NSFileManager's `createFileAtPath:` is used just for old code compatibility and will not trigger any delegate methods, so it's useless for custom NSFileManager at all.
// And also, NSFileManager's `createFileAtPath:` can only grab underlying POSIX errno, but NSData can grab errors defined in NSCocoaErrorDomain, which is better for user to check.
if (![imageData writeToURL:fileURL options:self.config.diskCacheWritingOptions error:error]) {
return NO;
if (![imageData writeToURL:fileURL options:self.config.diskCacheWritingOptions error:nil]) {
return;
}
// disable iCloud backup
@ -358,8 +348,6 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
// ignore iCloud backup resource value error
[fileURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
}
return YES;
}
#pragma mark - Query and Retrieve Ops
@ -452,7 +440,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
}
}
return nil;
return data;
}
- (nullable UIImage *)diskImageForKey:(nullable NSString *)key {

View File

@ -57,8 +57,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
- (void)test05ClearMemoryCache{
XCTestExpectation *expectation = [self expectationWithDescription:@"Clear memory cache"];
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^(NSError * _Nullable error) {
expect(error).to.beNil();
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^{
[[SDImageCache sharedImageCache] clearMemory];
expect([[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey]).to.beNil;
[[SDImageCache sharedImageCache] diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) {
@ -185,8 +184,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
- (void)test21InitialDiskCount{
XCTestExpectation *expectation = [self expectationWithDescription:@"getDiskCount"];
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^(NSError * _Nullable error) {
expect(error).to.beNil();
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^{
expect([[SDImageCache sharedImageCache] getDiskCount]).to.equal(1);
[[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{
[expectation fulfill];
@ -207,8 +205,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
- (void)test33CachePathForExistingKey{
XCTestExpectation *expectation = [self expectationWithDescription:@"cachePathForKey inPath"];
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^(NSError * _Nullable error) {
expect(error).to.beNil();
[[SDImageCache sharedImageCache] storeImage:[self imageForTesting] forKey:kImageTestKey completion:^{
NSString *path = [[SDImageCache sharedImageCache] cachePathForKey:kImageTestKey];
expect(path).notTo.beNil;
[[SDImageCache sharedImageCache] removeImageForKey:kImageTestKey withCompletion:^{
@ -237,7 +234,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[self testImagePath]];
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
[[SDImageCache sharedImageCache] storeImageDataToDisk:imageData forKey:kImageTestKey error:nil];
[[SDImageCache sharedImageCache] storeImageDataToDisk:imageData forKey:kImageTestKey];
UIImage *storedImageFromMemory = [[SDImageCache sharedImageCache] imageFromMemoryCacheForKey:kImageTestKey];
expect(storedImageFromMemory).to.equal(nil);
@ -269,7 +266,7 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
UIImage *image = [[UIImage alloc] initWithContentsOfFile:testImagePath];
NSString *key = @"TestPNGImageEncodedToDataAndRetrieveToJPEG";
[cache storeImage:image imageData:nil forKey:key toDisk:YES completion:^(NSError * _Nullable error) {
[cache storeImage:image imageData:nil forKey:key toDisk:YES completion:^{
[cache clearMemory];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
@ -309,35 +306,19 @@ NSString *kImageTestKey = @"TestImageKey.jpg";
}
#endif
- (void)test41StoreImageDataToDiskWithError {
- (void)test41StoreImageDataToDiskWithCustomFileManager {
NSData *imageData = [NSData dataWithContentsOfFile:[self testImagePath]];
NSError *targetError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileWriteNoPermissionError userInfo:nil];
NSError *error = nil;
SDMockFileManager *fileManager = [[SDMockFileManager alloc] init];
fileManager.mockSelectors = @{NSStringFromSelector(@selector(createDirectoryAtPath:withIntermediateDirectories:attributes:error:)) : targetError};
SDImageCache *cache = [[SDImageCache alloc] initWithNamespace:@"test"
diskCacheDirectory:@"/"
fileManager:fileManager];
[cache storeImageDataToDisk:imageData
forKey:kImageTestKey
error:&error];
expect(fileManager.lastError).to.beNil();
XCTAssertEqual(error.code, NSFileWriteNoPermissionError);
}
- (void)test42StoreImageDataToDiskWithoutError {
NSData *imageData = [NSData dataWithContentsOfFile:[self testImagePath]];
NSError *error = nil;
SDMockFileManager *fileManager = [[SDMockFileManager alloc] init];
fileManager.mockSelectors = @{NSStringFromSelector(@selector(createDirectoryAtPath:withIntermediateDirectories:attributes:error:)) : [NSNull null]};
SDImageCache *cache = [[SDImageCache alloc] initWithNamespace:@"test"
diskCacheDirectory:@"/"
fileManager:fileManager];
// This disk cache path creation will be mocked with error.
SDImageCache *cache = [[SDImageCache alloc] initWithNamespace:@"test" diskCacheDirectory:@"/" fileManager:fileManager];
[cache storeImageDataToDisk:imageData
forKey:kImageTestKey
error:&error];
XCTAssertNil(error);
forKey:kImageTestKey];
expect(fileManager.lastError).equal(targetError);
}
#pragma mark Helper methods

View File

@ -11,6 +11,8 @@
// This is a mock class to provide custom error for methods
@interface SDMockFileManager : NSFileManager
@property (nonatomic, strong, readonly, nullable) NSError *lastError;
@property (nonatomic, copy, nullable) NSDictionary<NSString *, NSError *> *mockSelectors; // used to specify mocked selectors which will return NO with specify error instead of normal process. If you specify a NSNull, will use nil instead.
@end

View File

@ -10,11 +10,14 @@
@interface SDMockFileManager ()
@property (nonatomic, strong, nullable) NSError *lastError;
@end
@implementation SDMockFileManager
- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary<NSFileAttributeKey,id> *)attributes error:(NSError * _Nullable __autoreleasing *)error {
self.lastError = nil;
NSError *mockError = [self.mockSelectors objectForKey:NSStringFromSelector(_cmd)];
if ([mockError isEqual:[NSNull null]]) {
if (error) {
@ -25,6 +28,7 @@
if (error) {
*error = mockError;
}
self.lastError = mockError;
return NO;
} else {
return [super createDirectoryAtPath:path withIntermediateDirectories:createIntermediates attributes:attributes error:error];