Skip to content

Commit

Permalink
potentially problem when system load high: #79
Browse files Browse the repository at this point in the history
  • Loading branch information
ibireme committed Mar 27, 2016
1 parent dbef382 commit 745a0b7
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 35 deletions.
16 changes: 13 additions & 3 deletions YYWebImage/Categories/CALayer+YYWebImage.m
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,15 @@ - (void)yy_setImageWithURL:(NSURL *)imageURL
});
};

__block int32_t newSentinel = 0;
__weak typeof(setter) weakSetter = nil;
YYWebImageCompletionBlock _completion = ^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) {
__strong typeof(_self) self = _self;
BOOL setImage = (stage == YYWebImageStageFinished || stage == YYWebImageStageProgress) && image && !(options & YYWebImageOptionAvoidSetImage);
BOOL showFade = (options & YYWebImageOptionSetImageWithFadeAnimation);
dispatch_async(dispatch_get_main_queue(), ^{
if (setImage && self) {
BOOL sentinelChanged = weakSetter && weakSetter.sentinel != newSentinel;
if (setImage && self && !sentinelChanged) {
if (showFade) {
CATransition *transition = [CATransition animation];
transition.duration = stage == YYWebImageStageFinished ? _YYWebImageFadeTime : _YYWebImageProgressiveFadeTime;
Expand All @@ -160,11 +163,18 @@ - (void)yy_setImageWithURL:(NSURL *)imageURL
}
self.contents = (id)image.CGImage;
}
if (completion) completion(image, url, from, stage, error);
if (completion) {
if (sentinelChanged) {
completion(nil, url, YYWebImageFromNone, YYWebImageStageCancelled, nil);
} else {
completion(image, url, from, stage, error);
}
}
});
};

[setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
newSentinel = [setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
weakSetter = setter;
});


Expand Down
16 changes: 13 additions & 3 deletions YYWebImage/Categories/MKAnnotationView+YYWebImage.m
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,15 @@ - (void)yy_setImageWithURL:(NSURL *)imageURL
});
};

__block int32_t newSentinel = 0;
__weak typeof(setter) weakSetter = nil;
YYWebImageCompletionBlock _completion = ^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) {
__strong typeof(_self) self = _self;
BOOL setImage = (stage == YYWebImageStageFinished || stage == YYWebImageStageProgress) && image && !(options & YYWebImageOptionAvoidSetImage);
BOOL showFade = ((options & YYWebImageOptionSetImageWithFadeAnimation) && !self.highlighted);
dispatch_async(dispatch_get_main_queue(), ^{
if (setImage && self) {
BOOL sentinelChanged = weakSetter && weakSetter.sentinel != newSentinel;
if (setImage && self && !sentinelChanged) {
if (showFade) {
CATransition *transition = [CATransition animation];
transition.duration = stage == YYWebImageStageFinished ? _YYWebImageFadeTime : _YYWebImageProgressiveFadeTime;
Expand All @@ -160,11 +163,18 @@ - (void)yy_setImageWithURL:(NSURL *)imageURL
}
self.image = image;
}
if (completion) completion(image, url, from, stage, error);
if (completion) {
if (sentinelChanged) {
completion(nil, url, YYWebImageFromNone, YYWebImageStageCancelled, nil);
} else {
completion(image, url, from, stage, error);
}
}
});
};

[setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
newSentinel = [setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
weakSetter = setter;
});
});
}
Expand Down
32 changes: 26 additions & 6 deletions YYWebImage/Categories/UIButton+YYWebImage.m
Original file line number Diff line number Diff line change
Expand Up @@ -133,18 +133,28 @@ - (void)_yy_setImageWithURL:(NSURL *)imageURL
});
};

__block int32_t newSentinel = 0;
__weak typeof(setter) weakSetter = nil;
YYWebImageCompletionBlock _completion = ^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) {
__strong typeof(_self) self = _self;
BOOL setImage = (stage == YYWebImageStageFinished || stage == YYWebImageStageProgress) && image && !(options & YYWebImageOptionAvoidSetImage);
dispatch_async(dispatch_get_main_queue(), ^{
if (setImage && self) {
BOOL sentinelChanged = weakSetter && weakSetter.sentinel != newSentinel;
if (setImage && self && !sentinelChanged) {
[self setImage:image forState:state.integerValue];
}
if (completion) completion(image, url, from, stage, error);
if (completion) {
if (sentinelChanged) {
completion(nil, url, YYWebImageFromNone, YYWebImageStageCancelled, nil);
} else {
completion(image, url, from, stage, error);
}
}
});
};

[setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
newSentinel = [setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
weakSetter = setter;
});
});
}
Expand Down Expand Up @@ -304,18 +314,28 @@ - (void)_yy_setBackgroundImageWithURL:(NSURL *)imageURL
});
};

__block int32_t newSentinel = 0;
__weak typeof(setter) weakSetter = nil;
YYWebImageCompletionBlock _completion = ^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) {
__strong typeof(_self) self = _self;
BOOL setImage = (stage == YYWebImageStageFinished || stage == YYWebImageStageProgress) && image && !(options & YYWebImageOptionAvoidSetImage);
dispatch_async(dispatch_get_main_queue(), ^{
if (setImage && self) {
BOOL sentinelChanged = weakSetter && weakSetter.sentinel != newSentinel;
if (setImage && self && !sentinelChanged) {
[self setBackgroundImage:image forState:state.integerValue];
}
if (completion) completion(image, url, from, stage, error);
if (completion) {
if (sentinelChanged) {
completion(nil, url, YYWebImageFromNone, YYWebImageStageCancelled, nil);
} else {
completion(image, url, from, stage, error);
}
}
});
};

[setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
newSentinel = [setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
weakSetter = setter;
});
});
}
Expand Down
32 changes: 26 additions & 6 deletions YYWebImage/Categories/UIImageView+YYWebImage.m
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,14 @@ - (void)yy_setImageWithURL:(NSURL *)imageURL
});
};

__block int32_t newSentinel = 0;
__weak typeof(setter) weakSetter = nil;
YYWebImageCompletionBlock _completion = ^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) {
__strong typeof(_self) self = _self;
BOOL setImage = (stage == YYWebImageStageFinished || stage == YYWebImageStageProgress) && image && !(options & YYWebImageOptionAvoidSetImage);
dispatch_async(dispatch_get_main_queue(), ^{
if (setImage && self) {
BOOL sentinelChanged = weakSetter && weakSetter.sentinel != newSentinel;
if (setImage && self && !sentinelChanged) {
BOOL showFade = ((options & YYWebImageOptionSetImageWithFadeAnimation) && !self.highlighted);
if (showFade) {
CATransition *transition = [CATransition animation];
Expand All @@ -164,11 +167,18 @@ - (void)yy_setImageWithURL:(NSURL *)imageURL
}
self.image = image;
}
if (completion) completion(image, url, from, stage, error);
if (completion) {
if (sentinelChanged) {
completion(nil, url, YYWebImageFromNone, YYWebImageStageCancelled, nil);
} else {
completion(image, url, from, stage, error);
}
}
});
};

[setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
newSentinel = [setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
weakSetter = setter;
});
});
}
Expand Down Expand Up @@ -303,12 +313,15 @@ - (void)yy_setHighlightedImageWithURL:(NSURL *)imageURL
});
};

__block int32_t newSentinel = 0;
__weak typeof(setter) weakSetter = nil;
YYWebImageCompletionBlock _completion = ^(UIImage *image, NSURL *url, YYWebImageFromType from, YYWebImageStage stage, NSError *error) {
__strong typeof(_self) self = _self;
BOOL setImage = (stage == YYWebImageStageFinished || stage == YYWebImageStageProgress) && image && !(options & YYWebImageOptionAvoidSetImage);
BOOL showFade = ((options & YYWebImageOptionSetImageWithFadeAnimation) && self.highlighted);
dispatch_async(dispatch_get_main_queue(), ^{
if (setImage && self) {
BOOL sentinelChanged = weakSetter && weakSetter.sentinel != newSentinel;
if (setImage && self && !sentinelChanged) {
if (showFade) {
CATransition *transition = [CATransition animation];
transition.duration = stage == YYWebImageStageFinished ? _YYWebImageFadeTime : _YYWebImageProgressiveFadeTime;
Expand All @@ -318,11 +331,18 @@ - (void)yy_setHighlightedImageWithURL:(NSURL *)imageURL
}
self.highlightedImage = image;
}
if (completion) completion(image, url, from, stage, error);
if (completion) {
if (sentinelChanged) {
completion(nil, url, YYWebImageFromNone, YYWebImageStageCancelled, nil);
} else {
completion(image, url, from, stage, error);
}
}
});
};

[setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
newSentinel = [setter setOperationWithSentinel:sentinel url:imageURL options:options manager:manager progress:_progress transform:transform completion:_completion];
weakSetter = setter;
});
});
}
Expand Down
18 changes: 10 additions & 8 deletions YYWebImage/Categories/_YYWebImageSetter.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,17 @@ extern const NSTimeInterval _YYWebImageProgressiveFadeTime;
@interface _YYWebImageSetter : NSObject
/// Current image url.
@property (nullable, nonatomic, readonly) NSURL *imageURL;
/// Current sentinel.
@property (nonatomic, readonly) int32_t sentinel;

/// Create new operation for web image.
- (void)setOperationWithSentinel:(int32_t)sentinel
url:(nullable NSURL *)imageURL
options:(YYWebImageOptions)options
manager:(YYWebImageManager *)manager
progress:(nullable YYWebImageProgressBlock)progress
transform:(nullable YYWebImageTransformBlock)transform
completion:(nullable YYWebImageCompletionBlock)completion;
/// Create new operation for web image and return a sentinel value.
- (int32_t)setOperationWithSentinel:(int32_t)sentinel
url:(nullable NSURL *)imageURL
options:(YYWebImageOptions)options
manager:(YYWebImageManager *)manager
progress:(nullable YYWebImageProgressBlock)progress
transform:(nullable YYWebImageTransformBlock)transform
completion:(nullable YYWebImageCompletionBlock)completion;

/// Cancel and return a sentinel value. The imageURL will be set to nil.
- (int32_t)cancel;
Expand Down
19 changes: 10 additions & 9 deletions YYWebImage/Categories/_YYWebImageSetter.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ - (void)dealloc {
[_operation cancel];
}

- (void)setOperationWithSentinel:(int32_t)sentinel
url:(NSURL *)imageURL
options:(YYWebImageOptions)options
manager:(YYWebImageManager *)manager
progress:(YYWebImageProgressBlock)progress
transform:(YYWebImageTransformBlock)transform
completion:(YYWebImageCompletionBlock)completion {
- (int32_t)setOperationWithSentinel:(int32_t)sentinel
url:(NSURL *)imageURL
options:(YYWebImageOptions)options
manager:(YYWebImageManager *)manager
progress:(YYWebImageProgressBlock)progress
transform:(YYWebImageTransformBlock)transform
completion:(YYWebImageCompletionBlock)completion {
if (sentinel != _sentinel) {
if (completion) completion(nil, imageURL, YYWebImageFromNone, YYWebImageStageCancelled, nil);
return;
return _sentinel;
}

NSOperation *operation = [manager requestImageWithURL:imageURL options:options progress:progress transform:transform completion:completion];
Expand All @@ -65,11 +65,12 @@ - (void)setOperationWithSentinel:(int32_t)sentinel
if (sentinel == _sentinel) {
if (_operation) [_operation cancel];
_operation = operation;
OSAtomicIncrement32(&_sentinel);
sentinel = OSAtomicIncrement32(&_sentinel);
} else {
[operation cancel];
}
dispatch_semaphore_signal(_lock);
return sentinel;
}

- (int32_t)cancel {
Expand Down

0 comments on commit 745a0b7

Please sign in to comment.