Merge pull request #2986 from dreampiggy/feature_pass_set_operation_key
Feature pass the set operation key into context option from upstream. Fix the potential retain cycle if user use custom manager
This commit is contained in:
commit
c4aaa8c63c
|
@ -52,10 +52,19 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
|
|||
setImageBlock:(nullable SDSetImageBlock)setImageBlock
|
||||
progress:(nullable SDImageLoaderProgressBlock)progressBlock
|
||||
completed:(nullable SDInternalCompletionBlock)completedBlock {
|
||||
context = [context copy]; // copy to avoid mutable object
|
||||
if (context) {
|
||||
// copy to avoid mutable object
|
||||
context = [context copy];
|
||||
} else {
|
||||
context = [NSDictionary dictionary];
|
||||
}
|
||||
NSString *validOperationKey = context[SDWebImageContextSetImageOperationKey];
|
||||
if (!validOperationKey) {
|
||||
// pass through the operation key to downstream, which can used for tracing operation or image view class
|
||||
validOperationKey = NSStringFromClass([self class]);
|
||||
SDWebImageMutableContext *mutableContext = [context mutableCopy];
|
||||
mutableContext[SDWebImageContextSetImageOperationKey] = validOperationKey;
|
||||
context = [mutableContext copy];
|
||||
}
|
||||
self.sd_latestOperationKey = validOperationKey;
|
||||
[self sd_cancelImageLoadOperationWithKey:validOperationKey];
|
||||
|
@ -83,6 +92,11 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
|
|||
SDWebImageManager *manager = context[SDWebImageContextCustomManager];
|
||||
if (!manager) {
|
||||
manager = [SDWebImageManager sharedManager];
|
||||
} else {
|
||||
// remove this manager to avoid retain cycle (manger -> loader -> operation -> context -> manager)
|
||||
SDWebImageMutableContext *mutableContext = [context mutableCopy];
|
||||
mutableContext[SDWebImageContextCustomManager] = nil;
|
||||
context = [mutableContext copy];
|
||||
}
|
||||
|
||||
SDImageLoaderProgressBlock combinedProgressBlock = ^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
|
||||
|
|
|
@ -350,6 +350,32 @@
|
|||
[self waitForExpectationsWithCommonTimeout];
|
||||
}
|
||||
|
||||
- (void)testUIViewOperationKeyContextWorks {
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"UIView operation key context should pass through"];
|
||||
|
||||
UIView *view = [[UIView alloc] init];
|
||||
NSURL *originalImageURL = [NSURL URLWithString:kTestJPEGURL];
|
||||
SDWebImageManager *customManager = [[SDWebImageManager alloc] initWithCache:SDImageCachesManager.sharedManager loader:SDImageLoadersManager.sharedManager];
|
||||
customManager.optionsProcessor = [SDWebImageOptionsProcessor optionsProcessorWithBlock:^SDWebImageOptionsResult * _Nullable(NSURL * _Nullable url, SDWebImageOptions options, SDWebImageContext * _Nullable context) {
|
||||
// expect manager does not exist, avoid retain cycle
|
||||
expect(context[SDWebImageContextCustomManager]).beNil();
|
||||
// expect operation key to be the image view class
|
||||
expect(context[SDWebImageContextSetImageOperationKey]).equal(NSStringFromClass(view.class));
|
||||
return [[SDWebImageOptionsResult alloc] initWithOptions:options context:context];
|
||||
}];
|
||||
[view sd_internalSetImageWithURL:originalImageURL
|
||||
placeholderImage:nil
|
||||
options:0
|
||||
context:@{SDWebImageContextCustomManager: customManager}
|
||||
setImageBlock:nil
|
||||
progress:nil
|
||||
completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
|
||||
[self waitForExpectationsWithCommonTimeout];
|
||||
}
|
||||
|
||||
#pragma mark - Helper
|
||||
- (UIWindow *)window {
|
||||
if (!_window) {
|
||||
|
|
Loading…
Reference in New Issue