今天看到了一個檢測查看屏幕幀數(shù)的輪子——JPFPSStatus,就很好奇的去看了一下,發(fā)現(xiàn)不是很難,特此小記錄下。

JPFPSStatus效果圖
發(fā)現(xiàn)其核心代碼如下
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick:)];
[displayLink setPaused:YES];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
另外就是顯示和移除啦
- (void)displayLinkTick:(CADisplayLink *)link {
if (lastTime == 0) {
lastTime = link.timestamp;
return;
}
count++;
NSTimeInterval interval = link.timestamp - lastTime;
if (interval < 1) return;
lastTime = link.timestamp;
float fps = count / interval;
count = 0;
NSString *text = [NSString stringWithFormat:@"%d FPS",(int)round(fps)];
[fpsLabel setText: text];
}
- (void)dealloc {
[displayLink setPaused:YES];
[displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
說ji此處就是 CADisplayLink的運用,以及注意下將 runloop mode 改為NSRunLoopCommonModes就 OK 啦。
CADisplayLink
它是一個能讓我們以和屏幕刷新率相同的頻率將內(nèi)容畫到屏幕上的定時器。
CADisplayLink 以特定的模式注冊到runloop之后,每當屏幕需要刷新的時候,runloop就會調(diào)用CADisplayLink綁定的target上的selector,這時target可以讀到 CADisplayLink 的每次調(diào)用的時間戳,用來準備下一幀顯示需要的數(shù)據(jù)。
注意其這 duration、frameInterval 屬性
@property(readonly, nonatomic) CFTimeInterval duration;
@property(nonatomic) NSInteger frameInterval;
- duration: 提供了每幀之間的時間,也就是屏幕每次刷新之間的的時間。我們可以使用這個時間來計算出下一幀要顯示的UI的數(shù)值。但是 duration 只是個大概的時間,如果CPU忙于其它計算,就沒法保證以相同的頻率執(zhí)行屏幕的繪制操作,這樣會跳過幾次調(diào)用回調(diào)方法的機會。
- frameInterval: 是可讀可寫的NSInteger型值,標識間隔多少幀調(diào)用一次selector方法,默認值是1,即每幀都調(diào)用一次。如果每幀都調(diào)用一次的話,對于iOS設(shè)備來說那刷新頻率就是60HZ也就是每秒60次,如果將frameInterval 設(shè)為2 那么就會兩幀調(diào)用一次,也就是變成了每秒刷新30次。
PS: iOS設(shè)備的屏幕刷新頻率是固定的,CADisplayLink在正常情況下會在每次刷新結(jié)束都被調(diào)用,相對于 NSTimer 來說精確度相當高。特別是在UI相關(guān)的動畫或者顯示內(nèi)容使用 CADisplayLink比起用NSTimer的好處就是我們不需要在格外關(guān)心屏幕的刷新頻率了,因為它本身就是跟屏幕刷新同步的。
備注:
http://blog.csdn.net/wzzvictory/article/details/22417181
http://www.itdecent.cn/p/c35a81c3b9eb
https://github.com/joggerplus/JPFPSStatus