Merge pull request #2728 from dreampiggy/bugfix_sdanimatedimageview_init_image
Fix that SDAnimatedImageView initWithImage will skip the initialize logic and crash
This commit is contained in:
commit
e9eb60e506
|
@ -40,7 +40,10 @@ static NSUInteger SDDeviceFreeMemory() {
|
|||
return vm_stat.free_count * page_size;
|
||||
}
|
||||
|
||||
@interface SDAnimatedImageView () <CALayerDelegate>
|
||||
@interface SDAnimatedImageView () <CALayerDelegate> {
|
||||
NSRunLoopMode _runLoopMode;
|
||||
BOOL _initFinished; // Extra flag to mark the `commonInit` is called
|
||||
}
|
||||
|
||||
@property (nonatomic, strong, readwrite) UIImage *currentFrame;
|
||||
@property (nonatomic, assign, readwrite) NSUInteger currentFrameIndex;
|
||||
|
@ -123,9 +126,10 @@ static NSUInteger SDDeviceFreeMemory() {
|
|||
|
||||
- (void)commonInit
|
||||
{
|
||||
// Pay attention that UIKit's `initWithImage:` will trigger a `setImage:` during initialization before this `commonInit`.
|
||||
// So the properties which rely on this order, should using lazy-evaluation or do extra check in `setImage:`.
|
||||
self.shouldCustomLoopCount = NO;
|
||||
self.shouldIncrementalLoad = YES;
|
||||
self.lock = dispatch_semaphore_create(1);
|
||||
#if SD_MAC
|
||||
self.wantsLayer = YES;
|
||||
// Default value from `NSImageView`
|
||||
|
@ -134,9 +138,10 @@ static NSUInteger SDDeviceFreeMemory() {
|
|||
self.imageAlignment = NSImageAlignCenter;
|
||||
#endif
|
||||
#if SD_UIKIT
|
||||
self.runLoopMode = [[self class] defaultRunLoopMode];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
|
||||
#endif
|
||||
// Mark commonInit finished
|
||||
_initFinished = YES;
|
||||
}
|
||||
|
||||
- (void)resetAnimatedImage
|
||||
|
@ -240,17 +245,38 @@ static NSUInteger SDDeviceFreeMemory() {
|
|||
}
|
||||
|
||||
#if SD_UIKIT
|
||||
- (void)setRunLoopMode:(NSString *)runLoopMode
|
||||
- (void)setRunLoopMode:(NSRunLoopMode)runLoopMode
|
||||
{
|
||||
if (![@[NSDefaultRunLoopMode, NSRunLoopCommonModes] containsObject:runLoopMode]) {
|
||||
NSAssert(NO, @"Invalid run loop mode: %@", runLoopMode);
|
||||
_runLoopMode = [[self class] defaultRunLoopMode];
|
||||
} else {
|
||||
_runLoopMode = runLoopMode;
|
||||
if ([_runLoopMode isEqual:runLoopMode]) {
|
||||
return;
|
||||
}
|
||||
if (_displayLink) {
|
||||
if (_runLoopMode) {
|
||||
[_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:_runLoopMode];
|
||||
}
|
||||
if (runLoopMode.length > 0) {
|
||||
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:runLoopMode];
|
||||
}
|
||||
}
|
||||
_runLoopMode = [runLoopMode copy];
|
||||
}
|
||||
|
||||
- (NSRunLoopMode)runLoopMode
|
||||
{
|
||||
if (!_runLoopMode) {
|
||||
_runLoopMode = [[self class] defaultRunLoopMode];
|
||||
}
|
||||
return _runLoopMode;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (BOOL)shouldIncrementalLoad {
|
||||
if (!_initFinished) {
|
||||
return YES; // Defaults to YES
|
||||
}
|
||||
return _initFinished;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
- (NSOperationQueue *)fetchQueue
|
||||
{
|
||||
|
@ -269,6 +295,13 @@ static NSUInteger SDDeviceFreeMemory() {
|
|||
return _frameBuffer;
|
||||
}
|
||||
|
||||
- (dispatch_semaphore_t)lock {
|
||||
if (!_lock) {
|
||||
_lock = dispatch_semaphore_create(1);
|
||||
}
|
||||
return _lock;
|
||||
}
|
||||
|
||||
#if SD_MAC
|
||||
- (CVDisplayLinkRef)displayLink
|
||||
{
|
||||
|
|
|
@ -156,6 +156,20 @@ static const NSUInteger kTestGIFFrameCount = 5; // local TestImage.gif loop coun
|
|||
#endif
|
||||
}
|
||||
|
||||
- (void)test13AnimatedImageViewInitWithImage {
|
||||
// Test that -[SDAnimatedImageView initWithImage:] this convenience initializer not crash
|
||||
SDAnimatedImage *image = [SDAnimatedImage imageWithData:[self testAPNGPData]];
|
||||
SDAnimatedImageView *imageView;
|
||||
#if SD_UIKIT
|
||||
imageView = [[SDAnimatedImageView alloc] initWithImage:image];
|
||||
#else
|
||||
if (@available(macOS 10.12, *)) {
|
||||
imageView = [SDAnimatedImageView imageViewWithImage:image];
|
||||
}
|
||||
#endif
|
||||
expect(imageView.image).equal(image);
|
||||
}
|
||||
|
||||
- (void)test20AnimatedImageViewRendering {
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"test SDAnimatedImageView rendering"];
|
||||
SDAnimatedImageView *imageView = [[SDAnimatedImageView alloc] init];
|
||||
|
|
Loading…
Reference in New Issue