From 1442534f6dcdfb3b836e729ebf6265f8175b914a Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Sun, 27 Oct 2019 21:38:53 +0800 Subject: [PATCH] Fix the SDDisplayLink issue of default value, add test cases `testSDDisplayLink` --- SDWebImage/Private/SDDisplayLink.m | 8 ++++++-- Tests/Tests/SDUtilsTests.m | 32 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/SDWebImage/Private/SDDisplayLink.m b/SDWebImage/Private/SDDisplayLink.m index 2cee3bf9..e248b803 100644 --- a/SDWebImage/Private/SDDisplayLink.m +++ b/SDWebImage/Private/SDDisplayLink.m @@ -80,14 +80,18 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt - (CFTimeInterval)duration { #if SD_MAC CVTimeStamp outputTime = self.outputTime; - NSTimeInterval duration = (double)outputTime.videoRefreshPeriod / ((double)outputTime.videoTimeScale * outputTime.rateScalar); + NSTimeInterval duration = 0; + double periodPerSecond = (double)outputTime.videoTimeScale * outputTime.rateScalar; + if (periodPerSecond > 0) { + duration = (double)outputTime.videoRefreshPeriod / periodPerSecond; + } #elif SD_IOS || SD_TV #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" NSTimeInterval duration = self.displayLink.duration * self.displayLink.frameInterval; #pragma clang diagnostic pop #else - NSTimeInterval duration; + NSTimeInterval duration = 0; if (self.displayLink.isValid && self.currentFireDate != 0) { NSTimeInterval nextFireDate = CFRunLoopTimerGetNextFireDate((__bridge CFRunLoopTimerRef)self.displayLink); duration = nextFireDate - self.currentFireDate; diff --git a/Tests/Tests/SDUtilsTests.m b/Tests/Tests/SDUtilsTests.m index a63161b1..e25897e5 100644 --- a/Tests/Tests/SDUtilsTests.m +++ b/Tests/Tests/SDUtilsTests.m @@ -9,6 +9,7 @@ #import "SDTestCase.h" #import "SDWeakProxy.h" +#import "SDDisplayLink.h" #import "SDInternalMacros.h" @interface SDUtilsTests : SDTestCase @@ -41,6 +42,37 @@ expect([proxy.debugDescription isEqualToString:object.debugDescription]).beTruthy(); } +- (void)testSDDisplayLink { + XCTestExpectation *expectation1 = [self expectationWithDescription:@"Display Link Stop"]; + XCTestExpectation *expectation2 = [self expectationWithDescription:@"Display Link Start"]; + SDDisplayLink *displayLink = [SDDisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidRefresh:)]; + NSTimeInterval duration = displayLink.duration; // Initial value + expect(duration).equal(1.0 / 60); + [displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes]; + [displayLink start]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + expect(displayLink.isRunning).beTruthy(); + [displayLink stop]; + }); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + expect(displayLink.isRunning).beFalsy(); + [displayLink start]; + [expectation1 fulfill]; + }); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + expect(displayLink.isRunning).beTruthy(); + [displayLink stop]; + [expectation2 fulfill]; + }); + [self waitForExpectationsWithCommonTimeout]; +} + +- (void)displayLinkDidRefresh:(SDDisplayLink *)displayLink { + NSTimeInterval duration = displayLink.duration; // Running value + expect(duration).beGreaterThan(0.01); + expect(duration).beLessThan(0.02); +} + - (void)testSDScaledImageForKey { // Test nil expect(SDScaledImageForKey(nil, nil)).beNil();