preface

The higher the refresh frequency, the more pictures you can see per second, the clearer the screen will be, and the more natural it will feel to your eyes. On the contrary, the lower the refresh frequency, the more sluggish it will be. The refresh frequency for your eyes to feel smooth is 60 frames

CADisplayLink is a framerate-related component, similar to NSTimer, except that it is called once per frame. It comes from the QuartzCore framework, which can be understood as an important control for animation

The source address

FPS detection tool implementation

The main implementation logic is to use CADisplayLink to open a loop. Normally, 60 frames per second is called 60 times, so the number of calls divided by the difference between the start and end time of this second is the actual frame rate FPS

In addition, after all, the 1s is still 1s at the time of the delay, but the loop number will be reduced, because the delay time will not be fixed at the time of the last call 1s

Therefore:

Actual frame rate = number of calls/interval timeCopy the code

Checking FPS logic is divided into the following steps:

1. Initialize the loop using CADisplayLink. Initialize the count and beginTime parameters to calculate the frame rate

2. Time period is required to calculate the frame rate. For the first loop, save the initial time and go to Step 1

3. Time count + 1

4. Calculation: Time interval = local call time – start time, count/time interval is the frame rate (here if the time interval is less than 1s, it will not be calculated, no practical significance)

5. Frame rate = number of calls/time interval, can be rounded up or down, then the frame rate

6. Initialize count, update start time to the current time, and start the calculation of the next FPS

The core code implementation logic is as follows:

// Start the loop call
- (void)startMonitor {
    _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(loopLink:)];
    [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
//loop calls the callback
- (void)loopLink:(CADisplayLink *)link {
    // If the start time does not exist, the value is assigned, and the end is performed only once
    if (_beginTime == 0) {
        _beginTime = link.timestamp;
        return;
    }
    _count++;
    // End immediately after 1s
    CFTimeInterval delta = link.timestamp - _beginTime; // Get the interval
    if (delta < 1) return;
    
    // Calculate frame rate, frame rate = number of calls/interval
    NSInteger fpsCount = _count / delta; // The result is rounded down directly
    
    // If the external callback is implemented, the callback notifies the external frame rate
    if (_onUpdateBlock) _onUpdateBlock(fpsCount);
    
    // Initialize the start time and times to restart the framerate for the next 1s(a little over 1s)
    _beginTime = link.timestamp;
    _count = 0;
}
// Remove the loop call, which, like NSTimer, invalidate removes the timer from all runloopmodes
- (void)stopMonitor {
    if(_displayLink) { [_displayLink invalidate]; _displayLink = nil; }}Copy the code

The last

Its implementation logic on this point, the source code also added FPSLabel UI interface, can be used directly, go to try it