Example Github: WSL_FPS
FPS: Short for Frames Per Second, it means the number of frames transmitted per second, which can be understood as what we often call "refresh rate" (in Hz); FPS measures the amount of information used to store and display dynamic videos.The more frames per second, the smoother the picture will be displayed and the lower the FPS value, the more cartoon it will be, so this value can be used to measure the performance of the application in image rendering.
CADisplayLink is a display timer that synchronizes the display of user programs with the hardware refresh of the screen. The normal screen refresh rate in iOS systems is 60Hz (60 times per second).
CADisplayLink can call the specified selector with the frequency of screen refresh, that is, every time the screen refreshes, it can calculate the current screen refresh rate by counting the number of times this method executes per second in the selector method.
Introduction to CADisplayLink: https://www.jianshu.com/p/434ec6911148
Initialize CADisplayLink and monitor the FPS values as follows:
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick:)]; [_displayLink setPaused:YES]; [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; //This method is executed at the same frequency as the current screen refresh. Each time the screen is refreshed, it executes once. The number of times the refresh is executed in one second is the current FPS value. - (void)displayLinkTick:(CADisplayLink *)link{ // duration is read-only, indicating the interval between screen refreshes = 1/fps // timestamp is read-only, indicating when the last screen was rendered // FrameeInterval is the interval at which the timer is triggered. The default value is 1, which means it is consistent with the refresh rate of the screen. // NSLog(@"timestamp= %f duration= %f frameInterval= %f",link.timestamp, link.duration, frameInterval); //Time to initialize screen rendering if (_beginTime == 0) { _beginTime = link.timestamp; return; } //Refresh Count Accumulation _count++; //Time difference between just screen rendering and initial screen rendering NSTimeInterval interval = link.timestamp - _beginTime; if (interval < 1) { //Less than 1 second, continue counting refresh times return; } //refresh frequency float fps = _count / interval; if (self.FPSBlock != nil) { self.FPSBlock(fps); } //After 1 second, initialize time and number of times to restart monitoring _beginTime = link.timestamp; _count = 0; }
FPS values are displayed in a floating view for easy real-time viewing.The implementation of the suspension graph takes advantage of the features of UIWindow.
Introduction to UIWindow: https://www.jianshu.com/p/cda083e44abd
_fpsLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50)]; _fpsLabel.textAlignment = NSTextAlignmentCenter; _fpsLabel.backgroundColor = [UIColor orangeColor]; _fpsLabel.font = [UIFont systemFontOfSize:15]; _fpsLabel.alpha = 0.7; UIViewController * viewc = [[UIViewController alloc] init]; _window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 100, 50)]; _window.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2.0, 64); _window.windowLevel = UIWindowLevelAlert + 1; _window.layer.cornerRadius = 10; _window.clipsToBounds = YES; _window.rootViewController = viewc; [_window addSubview:_fpsLabel]; [_window makeKeyAndVisible]; UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)]; _window.userInteractionEnabled = YES; [_window addGestureRecognizer:pan];