ios利用RunLoop原理實(shí)現(xiàn)去監(jiān)控卡頓實(shí)例詳解

一、卡頓問(wèn)題的幾種原因

復(fù)雜 UI 、圖文混排的繪制量過(guò)大;
在主線程上做網(wǎng)絡(luò)同步請(qǐng)求;
在主線程做大量的 IO 操作;
運(yùn)算量過(guò)大,CPU 持續(xù)高占用;
死鎖和主子線程搶鎖。

二、監(jiān)測(cè)卡頓的思路

監(jiān)測(cè)FPS:

FPS 是一秒顯示的幀數(shù),也就是一秒內(nèi)畫面變化數(shù)量。如果按照動(dòng)畫片來(lái)說(shuō),動(dòng)畫片的 FPS 就是 24,是達(dá)不到 60 滿幀的。也就是說(shuō),對(duì)于動(dòng)畫片來(lái)說(shuō),24 幀時(shí)雖然沒有 60 幀時(shí)流暢,但也已經(jīng)是連貫的了,所以并不能說(shuō) 24 幀時(shí)就算是卡住了。 由此可見,簡(jiǎn)單地通過(guò)監(jiān)視 FPS 是很難確定是否會(huì)出現(xiàn)卡頓問(wèn)題了,所以我就果斷棄了通過(guò)監(jiān)視 FPS 來(lái)監(jiān)控卡頓的方案。
RunLoop:

通過(guò)監(jiān)控 RunLoop 的狀態(tài)來(lái)判斷是否會(huì)出現(xiàn)卡頓。RunLoop原理這里就不再多說(shuō),主要說(shuō)方法,首先明確loop的狀態(tài)有六個(gè)


image.png

我們需要監(jiān)測(cè)的狀態(tài)有兩個(gè):RunLoop 在進(jìn)入睡眠之前和喚醒后的兩個(gè) loop 狀態(tài)定義的值,分別是 kCFRunLoopBeforeSources 和 kCFRunLoopAfterWaiting ,也就是要觸發(fā) Source0 回調(diào)和接收 mach_port 消息兩個(gè)狀態(tài)。

三、如何檢查卡頓

說(shuō)下步驟:
創(chuàng)建一個(gè) CFRunLoopObserverContext 觀察者;
將創(chuàng)建好的觀察者 runLoopObserver 添加到主線程 RunLoop 的 common 模式下觀察;
創(chuàng)建一個(gè)持續(xù)的子線程專門用來(lái)監(jiān)控主線程的 RunLoop 狀態(tài);
一旦發(fā)現(xiàn)進(jìn)入睡眠前的 kCFRunLoopBeforeSources 狀態(tài),或者喚醒后的狀態(tài) kCFRunLoopAfterWaiting,在設(shè)置的時(shí)間閾值內(nèi)一直沒有變化,即可判定為卡頓;
dump 出堆棧的信息,從而進(jìn)一步分析出具體是哪個(gè)方法的執(zhí)行時(shí)間過(guò)長(zhǎng)


image.png

image.png

image.png

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容