前言
FPS平时接触比较多的相信就是游戏党了,它代表的是刷新频率,刷新频率越高,每秒看到的画面数量越多,屏幕也就越来越清晰,眼睛感觉也就越自然,相反,频率越低,则越卡顿,人眼睛感觉流畅的刷新频率为60帧
而CADisplayLink就与帧率相关的一个组件,与NSTimer类似,区别就是它是每一帧调用一次,来自于QuartzCore框架,可以理解为其可能就是做动画包含的重要控件
FPS检测工具实现
主要实现逻辑是使用CADisplayLink开启一个loop,正常来说一秒60帧,也就是调用60次,那么调用次数除以这一秒的开始和结束时间差就是实际帧率FPS
另外,毕竟卡顿的时候1s还是1s,可是loop次数就会响应减少,由于卡顿时间也不会固定在1s的时候调用最后一次
因此:
实际帧率 = 调用次数 / 间隔时间
检测FPS逻辑一共分为下面几个步骤:
1.使用CADisplayLink初始化loop,初始化调用次数count和开始时间参数beginTime,以便于计算帧率
2.计算帧率需要时间段,第一次loop时,保存初始时间,结束准备下一轮,回到步骤1
3.时间的调用次数count + 1
4.计算: 时间间隔 = 本地调用时间 - 开始时间,用调用次数count / 时间间隔就是帧率了(这里如果时间间隔小于1s则不计算,没有实际意义)
5.帧率 = 调用次数 / 时间间隔,可以向上或者向下取整,则就是帧率了
6.初始化调用次数count,更新开始时间为当前时间,开始下一轮FPS的计算
核心代码实现逻辑如下所示:
//开始loop调用
- (void)startMonitor {
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(loopLink:)];
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
//loop调用回调
- (void)loopLink:(CADisplayLink *)link {
//开始时间不存在则赋值,并结束,只会走一次
if (_beginTime == 0) {
_beginTime = link.timestamp;
return;
}
_count++;
//不够1s直接结束
CFTimeInterval delta = link.timestamp - _beginTime; //获取时间间隔
if (delta < 1) return;
//计算帧率,帧率 = 调用次数 / 时间间隔
NSInteger fpsCount = _count / delta; //结果直接向下取整
//外界实现回调的话,回调以通知外接帧率
if (_onUpdateBlock) _onUpdateBlock(fpsCount);
//初始化开始时间和次数,重新开始计算下1s(1s多一点)的帧率
_beginTime = link.timestamp;
_count = 0;
}
//移除loop调用,这个就和NSTimer一样了,invalidate会将计时器从所有RunloopMode中移除
- (void)stopMonitor {
if (_displayLink) {
[_displayLink invalidate];
_displayLink = nil;
}
}
最后
其实现逻辑就这么点了,源码中还加入了FPSLabel的UI界面,可以直接使用,快去试试吧