Quick fix the issue that UIImage.sd_decodeOptions cause retain cycle when pass custom cache in context option
Now the SDImageCoderWebImageContext does not pass the built-in options, only custom options will be passed, and deprecated in 5.14.0
This commit is contained in:
parent
9248fe561a
commit
b46fe38c72
|
@ -13,6 +13,37 @@
|
|||
#import "UIImage+Metadata.h"
|
||||
#import "SDInternalMacros.h"
|
||||
|
||||
static NSArray<NSString *>* GetKnownContextOptions(void) {
|
||||
static NSArray<NSString *> *knownContextOptions;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
knownContextOptions =
|
||||
[NSArray arrayWithObjects:
|
||||
SDWebImageContextSetImageOperationKey,
|
||||
SDWebImageContextCustomManager,
|
||||
SDWebImageContextImageCache,
|
||||
SDWebImageContextImageLoader,
|
||||
SDWebImageContextImageCoder,
|
||||
SDWebImageContextImageTransformer,
|
||||
SDWebImageContextImageScaleFactor,
|
||||
SDWebImageContextImagePreserveAspectRatio,
|
||||
SDWebImageContextImageThumbnailPixelSize,
|
||||
SDWebImageContextQueryCacheType,
|
||||
SDWebImageContextStoreCacheType,
|
||||
SDWebImageContextOriginalQueryCacheType,
|
||||
SDWebImageContextOriginalStoreCacheType,
|
||||
SDWebImageContextOriginalImageCache,
|
||||
SDWebImageContextAnimatedImageClass,
|
||||
SDWebImageContextDownloadRequestModifier,
|
||||
SDWebImageContextDownloadResponseModifier,
|
||||
SDWebImageContextDownloadDecryptor,
|
||||
SDWebImageContextCacheKeyFilter,
|
||||
SDWebImageContextCacheSerializer
|
||||
, nil];
|
||||
});
|
||||
return knownContextOptions;
|
||||
}
|
||||
|
||||
SDImageCoderOptions * _Nonnull SDGetDecodeOptionsFromContext(SDWebImageContext * _Nullable context, SDWebImageOptions options, NSString * _Nonnull cacheKey) {
|
||||
BOOL decodeFirstFrame = SD_OPTIONS_CONTAINS(options, SDWebImageDecodeFirstFrameOnly);
|
||||
NSNumber *scaleValue = context[SDWebImageContextImageScaleFactor];
|
||||
|
@ -34,7 +65,10 @@ SDImageCoderOptions * _Nonnull SDGetDecodeOptionsFromContext(SDWebImageContext *
|
|||
mutableCoderOptions[SDImageCoderDecodeScaleFactor] = @(scale);
|
||||
mutableCoderOptions[SDImageCoderDecodePreserveAspectRatio] = preserveAspectRatioValue;
|
||||
mutableCoderOptions[SDImageCoderDecodeThumbnailPixelSize] = thumbnailSizeValue;
|
||||
mutableCoderOptions[SDImageCoderWebImageContext] = context;
|
||||
// Hack to remove all known context options before SDWebImage 5.14.0
|
||||
SDImageCoderMutableOptions *mutableContext = [NSMutableDictionary dictionaryWithDictionary:context];
|
||||
[mutableContext removeObjectsForKeys:GetKnownContextOptions()];
|
||||
mutableCoderOptions[SDImageCoderWebImageContext] = [mutableContext copy];
|
||||
SDImageCoderOptions *coderOptions = [mutableCoderOptions copy];
|
||||
|
||||
return coderOptions;
|
||||
|
|
|
@ -91,7 +91,9 @@ FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeEmbedThumb
|
|||
A SDWebImageContext object which hold the original context options from top-level API. (SDWebImageContext)
|
||||
This option is ignored for all built-in coders and take no effect.
|
||||
But this may be useful for some custom coders, because some business logic may dependent on things other than image or image data information only.
|
||||
Only the unknown context from top-level API (See SDWebImageDefine.h) may be passed in during image loading.
|
||||
See `SDWebImageContext` for more detailed information.
|
||||
@warning This option will be removed in 5.14.0
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderWebImageContext API_DEPRECATED("The coder component will be seperated from Core subspec in the future. Update your code to not rely on this context option.", macos(10.10, API_TO_BE_DEPRECATED), ios(8.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED), watchos(2.0, API_TO_BE_DEPRECATED));
|
||||
|
||||
|
|
|
@ -538,6 +538,18 @@
|
|||
[self waitForExpectationsWithTimeout:kAsyncTestTimeout * 5 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test20ThatContextPassedToLoaderDoesNotContainsBuiltIn {
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"The SDImageCoderWebImageContext should contains only unknown context to avoid retain cycle"];
|
||||
NSURL *url = [NSURL URLWithString:@"http://via.placeholder.com/502x502.png"];
|
||||
[SDWebImageManager.sharedManager loadImageWithURL:url options:0 context:@{SDWebImageContextImageScaleFactor : @(2), @"Foo": @"Bar"} progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
|
||||
SDImageCoderOptions *decodeOptions = image.sd_decodeOptions;
|
||||
SDWebImageContext *retrievedContext = decodeOptions[SDImageCoderWebImageContext];
|
||||
expect(retrievedContext[@"Foo"]).equal(@"Bar");
|
||||
[expectation fulfill];
|
||||
}];
|
||||
[self waitForExpectationsWithCommonTimeout];
|
||||
}
|
||||
|
||||
- (NSString *)testJPEGPath {
|
||||
NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
|
||||
return [testBundle pathForResource:@"TestImage" ofType:@"jpg"];
|
||||
|
|
Loading…
Reference in New Issue