看到的翻譯比較爛,看原文的同時(shí)順便紀(jì)錄下
原文鏈接
Instruments Tutorial with Swift: Getting Started
這篇教程會(huì)告訴你如何使用xcode自帶的Instruments的幾個(gè)比較重要的功能。可以讓你檢查你代碼中的運(yùn)行問(wèn)題,內(nèi)存問(wèn)題,循環(huán)引用和其它一些問(wèn)題。
Time for Profiling
首先我們來(lái)看Time for Profiling。每個(gè)標(biāo)準(zhǔn)時(shí)間,Instruments會(huì)暫停程序的運(yùn)行并且獲取每個(gè)正在運(yùn)行的線程的堆棧信息。類(lèi)似xocde中斷點(diǎn)時(shí)左邊欄show the debug navigator標(biāo)簽中的線程信息。
Time Profiler中如下圖
該圖中通過(guò)Call Tree顯示了app中許多方法執(zhí)行使用的時(shí)間。每一行都是一個(gè)通過(guò)執(zhí)行路徑表明的不同方法。
此處的時(shí)間并不是嚴(yán)格的通過(guò)監(jiān)視開(kāi)始結(jié)束確定的,而是通過(guò)方法在棧中停留的樣本次數(shù)確定的。舉例來(lái)說(shuō),如果1毫秒一次取100個(gè)樣本,而我們要觀察的方法在其中10個(gè)樣本中出現(xiàn)在棧頂部,那么我們就可以推斷這個(gè)方法用時(shí)大約是10毫秒,這個(gè)方法非常不嚴(yán)謹(jǐn)?shù)亲鳛槲覀儥z查是否有方法用時(shí)過(guò)長(zhǎng)(找到有問(wèn)題的方法)已經(jīng)完全夠用了。
提示:一般情況下,你應(yīng)該使用真機(jī)而不是模擬器進(jìn)行測(cè)試。模擬器基于mac的硬件,相比iOS設(shè)備過(guò)于強(qiáng)大,在真機(jī)中有很多限制是模擬器沒(méi)有的。
所以不需要其它的操作,時(shí)間就被紀(jì)錄下來(lái)了。
下面看看具體使用。
打開(kāi)你的xcode在菜單欄中 選擇Product\Profile,或者直接快捷鍵?I。這將會(huì)編譯你的app并且載入Instruments。接下來(lái)你將會(huì)看到Instruments提供的各種模版,如下圖。
選擇Time Profiler然后點(diǎn)擊choose。然后會(huì)彈出一個(gè)新的Instruments界面。點(diǎn)擊左上角的紅色記錄按鈕開(kāi)始記錄數(shù)據(jù),這時(shí)app也會(huì)在設(shè)備中打開(kāi)。當(dāng)然你可能會(huì)碰到需要授權(quán)的情況,點(diǎn)擊是就好。
在Instruments窗口中你可以看到title位置的時(shí)間正在增長(zhǎng),時(shí)間軸上又個(gè)小三角自左向右移動(dòng),這表明app已經(jīng)在運(yùn)行了。
首先右上角把右邊欄和下邊欄都打開(kāi),如下

下面解釋各個(gè)部分
1.記錄控制。紅色的‘記錄’按鈕,控制被分析的app運(yùn)行或者終止。暫停按鈕就是暫停嘍
2.運(yùn)行中的計(jì)時(shí)器。顯示被分析的app運(yùn)行的時(shí)間,和運(yùn)行次數(shù)。如果你停止或者重新開(kāi)始記錄,會(huì)開(kāi)啟一個(gè)新的計(jì)時(shí)器并且顯示 Run 2 of 2。
3.這個(gè)部分叫做追蹤區(qū)域,顯示各種數(shù)據(jù)的軌跡。根據(jù)所選的Time Profiler模型,現(xiàn)在只有一個(gè)instrument所以只有一行軌跡,詳細(xì)的稍后介紹
4.詳細(xì)展示。這部分顯示你所追蹤的instrument的詳細(xì)信息。當(dāng)前,它顯示的是最‘熱門(mén)’的方法--占用cpu時(shí)間最長(zhǎng)的。
5.檢查器面板。三個(gè)檢查器:記錄設(shè)置,顯示設(shè)置,拓展詳情。
原文中有例子來(lái)說(shuō)明,可以下載后按照下面順著走。例子大概是一個(gè)搜索后展示結(jié)果的列表。
實(shí)戰(zhàn)
例子用Time Profiler跑起來(lái)后,搜索個(gè)東西然后在列表中上下滑動(dòng)幾次,就可以記錄到不少Time Profiler的數(shù)據(jù)。你會(huì)發(fā)現(xiàn)屏幕中間的數(shù)字變了并且有曲線圖出現(xiàn),這表示CPU周期在被使用。
如果你不希望這么繁瑣的數(shù)據(jù),只想觀看指定的可能出錯(cuò)的東西,那么你需要對(duì)上面的5進(jìn)行一些設(shè)置。選擇Display Settings(?+2)。在檢查器中的Call Tree中,選擇Separate by Thread, Invert Call Tree, Hide Missing Symbols 和 Hide System Libraries. 如下圖
下面解釋下這些選項(xiàng)都有什么用
- Separate by Thread:每個(gè)線程分開(kāi)觀察。這可以讓你知道哪個(gè)線程改為cpu的高負(fù)荷負(fù)責(zé)。
- Invert Call Tree:字面意思,從top到bottom展示。介于你想知道CPU把時(shí)間都花到哪個(gè)深層的方法中,一般都會(huì)選這個(gè)。
- Hide Missing Symbols:如果你app或者系統(tǒng)framework的dsym文件沒(méi)有被找到,你就不會(huì)在表區(qū)看到對(duì)應(yīng)的方法名,只能看到2進(jìn)制文件中對(duì)應(yīng)的地址。如果選中這個(gè),那么只有確定的標(biāo)示才會(huì)被顯示出來(lái),只有地址的會(huì)被隱藏。用來(lái)簡(jiǎn)化分析的數(shù)據(jù)。
- Hide System Libraries:當(dāng)你選中該選項(xiàng),只有你app的標(biāo)示(例子中為方法)會(huì)被顯示。通常都會(huì)被選中,因?yàn)殛P(guān)注系統(tǒng)本身使用cpu的情況并沒(méi)有什么卵用。
- Flatten Recursion:處理遞歸(自己調(diào)用自己),在每個(gè)棧中只跟蹤一個(gè),而不是多個(gè)。
- Top Functions:選中意味著,讓Instruments統(tǒng)計(jì)一個(gè)方法使用時(shí)間時(shí),將它調(diào)用的方法的運(yùn)行時(shí)間也算到里面。當(dāng)A調(diào)用B,那么A的時(shí)間為A的時(shí)間加上B的。這個(gè)是很有用的,可以讓你發(fā)現(xiàn)進(jìn)棧太長(zhǎng)的元素。
-
如果是OC的程序,這里還有個(gè) Show Obj-C Only:如果選中,那么只會(huì)顯示oc的方法,忽略c和c++。這個(gè)沒(méi)什么卵用,除非你的app是個(gè) OpenGL app,會(huì)有一些C++的方法。
回到我們的例子中
雖然原來(lái)表中好多值都好類(lèi)似,一旦你設(shè)置了上面的選項(xiàng)就會(huì)被梳理成下面這樣
現(xiàn)在看起來(lái)好多了。你會(huì)發(fā)現(xiàn)大量的時(shí)間被花費(fèi)到applytonalfilter這個(gè)方法中,這個(gè)方法在cell每次出現(xiàn)都會(huì)被調(diào)用。
為了知道這個(gè)方法到底在做些什么,列表中直接雙擊,會(huì)直接把代碼展示給你看。如下
超贊,有木有。applyTonalFilter()是UIImage拓展的方法 ,時(shí)間基本都用來(lái)生成輸出圖像。
看上去這個(gè)方法我們也做不了什么讓他變快。讓我們?nèi)タ纯凑{(diào)用這個(gè)方法的方法看看。點(diǎn)擊代碼上方的calltree回到列表視圖?,F(xiàn)在我們點(diǎn)擊applyTonalFilter這行左邊的小三角,展開(kāi)調(diào)用該方法的方法。重復(fù)步驟(在swift中,層數(shù)稍微多一些)當(dāng)你看到有你工程名字的一行時(shí),有可能就找到問(wèn)題了。
例子中這一行是 cellForItemAtIndexPath,雙擊打開(kāi)代碼。現(xiàn)在你就能看到問(wèn)題所在了。這個(gè)方法耗時(shí)太長(zhǎng),而你在cell重構(gòu)填充圖片時(shí)不停的被調(diào)用造成了主線程的阻塞(UI展示在主線程中進(jìn)行,所以影響到了UI流暢)。
轉(zhuǎn)進(jìn)工程代碼
為了解決這個(gè),你需要做兩步:第一將圖片處理放到后臺(tái)線程中,第二當(dāng)圖片生成好后保存下來(lái)。例子中有集成緩存方法。
現(xiàn)在點(diǎn)擊右上角的xcode標(biāo)志,飛機(jī)票直接到問(wèn)題代碼?,F(xiàn)在改吧。
未完待續(xù),還有其他模塊要說(shuō)。不過(guò)我要先去測(cè)測(cè)我的代碼了。