iOS-卡頓監(jiān)測-FPS監(jiān)測(附詳細代碼及原理講解)

序言

一個應用的好壞很大程度上取決于使用是否流暢叶撒,所以明白造成應用卡頓的原因及解決思路顯的至關重要。

一 檢測的方案根據(jù)線程是否相關分為兩大類:
  • 執(zhí)行耗時任務會導致CPU短時間無法響應其他任務,檢測任務耗時來判斷是否可能導致卡頓

  • 由于卡頓直接表現(xiàn)為操作無響應白胀,界面動畫遲緩,檢測主線程是否能響應任務來判斷是否卡頓

與主線程相關的檢測方案包括:

  • fps
  • ping
  • runloop

與主線程不相關的檢測包括:

  • stack backtrace
  • msgSend observe
二 FPS 監(jiān)測

通常情況下,屏幕會保持60hz/s的刷新速度纽甘,每次刷新時會發(fā)出一個屏幕刷新信號CADisplayLink允許我們注冊一個與刷新信號同步的回調(diào)處理抽碌『酚可以通過屏幕刷新機制來展示fps值:

方法一

附核心代碼

@implementation ViewController {
    UILabel *_fpsLbe;
    
    CADisplayLink *_link;
    NSTimeInterval _lastTime;
    float _fps;
}

- (void)startMonitoring {
    if (_link) {
        [_link removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
        [_link invalidate];
        _link = nil;
    }
    _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(fpsDisplayLinkAction:)];
    [_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

- (void)fpsDisplayLinkAction:(CADisplayLink *)link {
    if (_lastTime == 0) {
        _lastTime = link.timestamp;
        return;
    }
    
    self.count++;
    NSTimeInterval delta = link.timestamp - _lastTime;
    if (delta < 1) return;
    _lastTime = link.timestamp;
    _fps = _count / delta;
    NSLog(@"count = %d, delta = %f,_lastTime = %f, _fps = %.0f",_count, delta, _lastTime, _fps);
    self.count = 0;
    _fpsLbe.text = [NSString stringWithFormat:@"FPS:%.0f",_fps];
}

運行效果圖

1.gif

監(jiān)聽count值的改變

#pragma mark - observer

- (void)addObserver {
    [self addObserver:self forKeyPath:@"count" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    NSLog(@"count new = %@, old = %@",[change valueForKey:@"new"], [change valueForKey:@"old"]);
}
image.png

分析

1.通過打印母怜,我們知道每次刷新時會發(fā)出一個屏幕刷新信號爷辙,則與刷新信號同步的回調(diào)方法`fpsDisplayLinkAction:`會調(diào)用,然后count加一褐墅。
2.每隔一秒痴颊,我們計算一次 `fps `值赏迟,用一個變量_lastTime記錄上一次計算 fps 值的時間,然后將 count 的值除以時間間隔蠢棱,就得到了 fps 的值锌杀,在將_lastTime重新賦值,_count置成零泻仙。
3.正常情況下糕再,屏幕會保持60hz/s的刷新速度,所以1秒內(nèi)`fpsDisplayLinkAction:`方法會調(diào)用60次玉转。fps 計算的值為0突想,就不卡頓,流暢冤吨。
4.如果1秒內(nèi)`fpsDisplayLinkAction:`只回調(diào)了50次蒿柳,計算出來的fps就是 _count / delta(時間間隔) 。
方法二

核心代碼

- (void)startFpsMonitoring {
    _link = [CADisplayLink displayLinkWithTarget: self selector: @selector(displayFps:)];
    [_link addToRunLoop: [NSRunLoop mainRunLoop] forMode: NSRunLoopCommonModes];
}

- (void)displayFps: (CADisplayLink *)fpsDisplay {
    self.count++;
    CFAbsoluteTime threshold = CFAbsoluteTimeGetCurrent() - _lastTime;
    if (threshold >= 1.0) {
        _fps = (_count / threshold);
        _lastTime = CFAbsoluteTimeGetCurrent();
        _fpsLbe.text = [NSString stringWithFormat:@"FPS:%.0f",_fps];
        self.count = 0;
        NSLog(@"count = %d,_lastTime = %f, _fps = %.0f",_count, _lastTime, _fps);
    }
}

運行結果和方法一差不多漩蟆。

結論

image.png

本文參考 質(zhì)量監(jiān)控-卡頓檢測垒探,感謝該作者。


項目連接地址 - FpsMonitoring

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怠李,一起剝皮案震驚了整個濱河市圾叼,隨后出現(xiàn)的幾起案子蛤克,更是在濱河造成了極大的恐慌,老刑警劉巖夷蚊,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件构挤,死亡現(xiàn)場離奇詭異,居然都是意外死亡惕鼓,警方通過查閱死者的電腦和手機筋现,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來箱歧,“玉大人矾飞,你說我怎么就攤上這事⊙叫希” “怎么了洒沦?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長价淌。 經(jīng)常有香客問我申眼,道長,這世上最難降的妖魔是什么蝉衣? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任括尸,我火速辦了婚禮,結果婚禮上买乃,老公的妹妹穿的比我還像新娘姻氨。我一直安慰自己钓辆,他們只是感情好剪验,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著前联,像睡著了一般功戚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上似嗤,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天啸臀,我揣著相機與錄音,去河邊找鬼烁落。 笑死乘粒,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的伤塌。 我是一名探鬼主播灯萍,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼每聪!你這毒婦竟也來了旦棉?” 一聲冷哼從身側響起齿风,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绑洛,沒想到半個月后救斑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡真屯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年脸候,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绑蔫。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡纪他,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晾匠,到底是詐尸還是另有隱情茶袒,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布凉馆,位于F島的核電站薪寓,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏澜共。R本人自食惡果不足惜向叉,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嗦董。 院中可真熱鬧母谎,春花似錦、人聲如沸京革。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匹摇。三九已至咬扇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間廊勃,已是汗流浹背懈贺。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留坡垫,地道東北人梭灿。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像冰悠,于是被迫代替她去往敵國和親堡妒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容