
FPS.gif
示例Github:WSL_FPS
FPS :Frames Per Second 的簡稱縮寫,意思是每秒傳輸幀數(shù),可以理解為我們常說的“刷新率”(單位為Hz);FPS是測量用于保存、顯示動態(tài)視頻的信息數(shù)量。每秒鐘幀數(shù)愈多,所顯示的畫面就會愈流暢,fps值越低就越卡頓,所以這個值在一定程度上可以衡量應(yīng)用在圖像繪制渲染處理時的性能。
CADisplayLink 是一個用于顯示的定時器, 它可以讓用戶程序的顯示與屏幕的硬件刷新保持同步,iOS系統(tǒng)中正常的屏幕刷新率為60Hz(60次每秒)。
CADisplayLink可以以屏幕刷新的頻率調(diào)用指定selector,也就是說每次屏幕刷新的時候就調(diào)用selector,那么只要在selector方法里面統(tǒng)計每秒這個方法執(zhí)行的次數(shù),通過次數(shù)/時間就可以得出當前屏幕的刷新率了。
CADisplayLink 簡介:http://www.itdecent.cn/p/434ec6911148
初始化CADisplayLink,監(jiān)測FPS值的代碼如下:
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick:)];
[_displayLink setPaused:YES];
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
//這個方法的執(zhí)行頻率跟當前屏幕的刷新頻率是一樣的,屏幕每渲染刷新一次,就執(zhí)行一次,那么1秒的時長執(zhí)行刷新的次數(shù)就是當前的FPS值
- (void)displayLinkTick:(CADisplayLink *)link{
// duration 是只讀的, 表示屏幕刷新的間隔 = 1/fps
// timestamp 是只讀的, 表示上次屏幕渲染的時間點
// frameInterval 是表示定時器被觸發(fā)的間隔, 默認值是1, 就是表示跟屏幕的刷新頻率一致。
// NSLog(@"timestamp= %f duration= %f frameInterval= %f",link.timestamp, link.duration, frameInterval);
//初始化屏幕渲染的時間
if (_beginTime == 0) {
_beginTime = link.timestamp;
return;
}
//刷新次數(shù)累加
_count++;
//剛剛屏幕渲染的時間與最開始幕渲染的時間差
NSTimeInterval interval = link.timestamp - _beginTime;
if (interval < 1) {
//不足1秒,繼續(xù)統(tǒng)計刷新次數(shù)
return;
}
//刷新頻率
float fps = _count / interval;
if (self.FPSBlock != nil) {
self.FPSBlock(fps);
}
//1秒之后,初始化時間和次數(shù),重新開始監(jiān)測
_beginTime = link.timestamp;
_count = 0;
}
FPS的值用懸浮視圖來展示,方便實時查看。懸浮圖的實現(xiàn)是利用了UIWindow的特性來實現(xiàn)的。
UIWindow簡介: http://www.itdecent.cn/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];