From e1d96e7812f97b03db1f2500ef480a398f016e2a Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Fri, 13 Apr 2018 16:48:15 +0800 Subject: [PATCH] Revert "Merge pull request #1898 from walkline/master into 5.x" --- SDWebImage/SDImageCache.h | 14 ++++----- SDWebImage/SDImageCache.m | 52 +++++++++++++-------------------- Tests/Tests/SDImageCacheTests.m | 43 ++++++++------------------- Tests/Tests/SDMockFileManager.h | 2 ++ Tests/Tests/SDMockFileManager.m | 4 +++ 5 files changed, 43 insertions(+), 72 deletions(-) diff --git a/SDWebImage/SDImageCache.h b/SDWebImage/SDImageCache.h index 81b5bc23..cb5a0f0a 100644 --- a/SDWebImage/SDImageCache.h +++ b/SDWebImage/SDImageCache.h @@ -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 diff --git a/SDWebImage/SDImageCache.m b/SDWebImage/SDImageCache.m index 1b6683c0..c66e7b9b 100644 --- a/SDWebImage/SDImageCache.m +++ b/SDWebImage/SDImageCache.m @@ -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 { diff --git a/Tests/Tests/SDImageCacheTests.m b/Tests/Tests/SDImageCacheTests.m index 4a53c7c2..948e3adb 100644 --- a/Tests/Tests/SDImageCacheTests.m +++ b/Tests/Tests/SDImageCacheTests.m @@ -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 diff --git a/Tests/Tests/SDMockFileManager.h b/Tests/Tests/SDMockFileManager.h index d93d1ac4..71f2aceb 100644 --- a/Tests/Tests/SDMockFileManager.h +++ b/Tests/Tests/SDMockFileManager.h @@ -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 *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 diff --git a/Tests/Tests/SDMockFileManager.m b/Tests/Tests/SDMockFileManager.m index 472797fb..bf8cda58 100644 --- a/Tests/Tests/SDMockFileManager.m +++ b/Tests/Tests/SDMockFileManager.m @@ -10,11 +10,14 @@ @interface SDMockFileManager () +@property (nonatomic, strong, nullable) NSError *lastError; + @end @implementation SDMockFileManager - (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)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];