Time Profile原理
如果要反應(yīng)CPU使用情況,第一反應(yīng)是記錄每個方法執(zhí)行時間。然后根據(jù)調(diào)用堆棧把每個方法執(zhí)行的時間累加起來,呈現(xiàn)給使用者來反應(yīng)CPU使用情況。Time Profile并沒有事無巨細的記錄每個方法的執(zhí)行時間,而是使用了定時采樣方式來反應(yīng)CPU使用情況。
每隔1ms,Time Profile會記錄一下當前執(zhí)行堆棧,就像Xcode中斷點調(diào)試那樣的堆棧。如果1s內(nèi)CPU都在忙碌,Time Profile會截取到1000個堆棧,這1s中的Detail pane中的Call Tree就根據(jù)堆棧的調(diào)用結(jié)構(gòu)組織起來的,所以Time Profile Call Tree和調(diào)用堆??雌饋砗芟?,實際上Time Profile Call Tree等于每個時間點調(diào)用堆棧的疊加
如果把Time Line拉到足夠大,還能看到樣本標記,可以在Detail pane中選中sample來看采集到的樣本

在分析CPU圖譜,有兩個很重要的概念,weight 和 self weight

weight:指定時間,此方法在采樣堆棧出現(xiàn)的次數(shù)。eg:weight 46ms,就是這段時間里,此方法被采樣46次
self weight:指定時間,此方法處于堆棧最后面的次數(shù)。eg1:self weight 1ms,就是這段時間里,采樣時,此方法在調(diào)用堆棧最后面1次;eg2:self weight 0ms,就是這段時間里,采樣時此方法一次也沒有在調(diào)用堆棧最后面,也就是這個方法并沒有干實事,全是調(diào)用其他方法做事的
實操
先使用instrument捕捉CPU使用情況,然后
- 在time line上選出想要分析的片段
- 選中想要分析的線程,分析卡頓就選中主線程,樓主一般都是分析主線程
- 沿著占用CPU高的方法,一級一級展開call tree,分析調(diào)用

分析:
可以看到使用CPU最多的是CA::Context::commit_transaction(CA:Transaction*),這是系統(tǒng)渲染的方法,所以可以知道,是由于需要渲染的東西太多了,導(dǎo)致的卡頓(不知道這個是系統(tǒng)渲染的方法也沒關(guān)系,繼續(xù)往call tree找就能看出來)。
繼續(xù)沿著CPU使用率高的方法往下找,能看到這樣的情況

不知道CA::Context::commit_transaction(CA:Transaction*)的,從這里就可以看出,是UILabel渲染占了很多CPU
找到這里就算交差了嗎?是渲染耗時多所以就沒辦法解決了嗎?
本著科學(xué)認真(杠精)的態(tài)度,我決定嘗試分析這些渲染是不是有水分(有沒有不必要渲染、重復(fù)渲染)
我的頁面有很多UILable,首先我需要知道這些UILabel的渲染占比。我采取的方法是,繼續(xù)往下找,找到我可以控制的方法為止,像下面

然后重寫UILable,給每個UILabel起個標志性的名字,覆蓋drawTextInRect方法,這樣在instrument里就能區(qū)分各個UILabel的渲染耗時占比了

上面的圖并不是同一個CPU使用片段,只是用來示意如何區(qū)分不同UILabel的渲染。
到這里,可以找出是不是有不必要渲染。比如某個label是隱藏狀態(tài),但是占了渲染耗時,這是不必要的
至于重復(fù)渲染和更多的排除不必要渲染方法,等我想到再更。
作者水平有限,如有錯誤,還請不吝賜教