讀古今文學網 > iOS編程基礎:Swift、Xcode和Cocoa入門指南 > 9.9 分析 >

9.9 分析

Xcode提供了用於以圖形化和數字化形式探索應用內部行為的工具,你應該瞭解這些工具的使用方式。可以通過調試導航器中的儀表盤在應用運行時監控其關鍵指標,如CPU與內存使用。Instruments則是個複雜且強大的輔助應用,它會收集有助於追蹤問題的分析數據,並提供你所需要的數字化信息來改進應用的性能與響應性。在應用開發趨於結束之際,你應該花些時間瞭解一下Instruments的用法(眾所周知,過早的優化是萬惡之源)。

9.9.1 儀表盤

調試導航器中的儀表盤會在應用構建和運行時起作用。單擊某一項可以在編輯器中查看到進一步的細節信息。儀表盤並未提供非常詳盡的信息,不過它卻非常輕量級且總是處於激活狀態,因此可以通過它在任何時候瞭解到應用的總體運行情況。特別地,如果出現了問題,比如,長時間的高CPU使用率或內存使用不斷飆升,那就可以在儀表盤中定位到,然後通過Instruments找出問題所在。

有4種基本的儀表盤:CPU、內存、磁盤與網絡。根據環境的不同,你可能還會看到其他儀表盤。比如,在Xcode 7中,當在設備上運行時,電量儀表盤會出現;對於某些設備來說還可能會出現GPU儀表盤。如果應用使用了iCloud,那還會看到iCloud儀表盤。

在圖9-12中,我頻繁使用了應用一段時間,不斷重複地執行用戶可能會操作的最消耗內存的動作。這些動作會導致內存使用量攀升,不過應用的內存使用量最後會趨於平穩,因此我認為應用在內存使用量上是沒問題的。

圖9-12:調試導航儀表盤

值得注意的是,圖9-12是在設備上運行的結果。在模擬器上運行則會得到完全不同的結果,這個結果是不正確的。

9.9.2  Instruments

可以在模擬器或設備上使用Instruments。在設備上進行的是最終的測試,目的是得到盡可能準確的結果。

要使用Instruments,請在項目窗口工具欄的方案彈出菜單中設置所需的目標,然後選擇Product→Profile。這樣應用就會使用方案下的Profile動作進行構建;在默認情況下,這會使用發佈構建配置,這可能就是你所期望的。如果在設備上運行,那麼你可能會看到一些驗證警告,不過可以忽略它們。Instruments會啟動;如果方案的Instrument彈出菜單將Profile動作設為了Ask on Launch(默認值),那麼Instruments就會彈出一個對話框,你可以從中選擇追蹤模板。

此外,還可以單擊調試導航器儀表盤編輯器中的Profile In Instruments;如果儀表盤發現了問題,你又想通過更為詳盡的Instruments監控來重現問題,這麼做就是很方便的。Instruments啟動後,選擇合適的追蹤模板。對話框會給出兩個選擇:Restart會先停止應用,然後使用Instruments再次啟動;Transfer則會保持應用的運行,並將Instruments掛接到應用中。

當Instruments的主窗口出現時,可以進一步對其定制來分析感興趣的數據,可以將Instruments窗口的結構保存為自定義模板。需要單擊Record按鈕,或選擇File→Record Trace來運行應用。現在,可以像用戶那樣與應用交互了,而Instruments則會記錄下統計數據。

如果之前將發佈配置的代碼簽名身份構建設置為iOS Distribution來歸檔或分發應用(本章後面將會介紹),那就無法在設備上使用Instruments進行分析了。必須要將該構建設置為iOS Developer。

Instruments的使用是個高級主題,這超出了本書的討論範圍。事實上,僅是介紹Instruments本身就可以寫一本書。要想瞭解進一步的信息,請參考Apple的文檔,特別是Instruments User Reference與Instruments User Guide。此外,往年的很多WWDC都有關於Instruments的視頻介紹;請查找名字中包含「Instruments」或「Performance」的資料。這裡僅僅簡單介紹一下Instruments到底能做什麼。

圖9-13展示了在Instruments中能夠完成與圖9-12調試導航器儀表盤所能完成的相同事情。我將目標設定為我的設備。選擇Product→Profile;當Instruments啟動後,我選擇Allocations追蹤模板。當應用在Instruments下運行時,我使用了一會兒,然後暫停了Instruments,與此同時它會繪製應用的內存使用情況表。查看這張表,我發現內存使用量最高達到了10MB,不過大部分時間,內存使用量都處在一個較低的水平上(不到4MB)。我對這個結果感到很滿意。

圖9-13:Instruments以圖形化形式展示了一段時間內的內存使用

Instruments的另一個強大之處就是檢測內存洩漏的能力。在圖9-14中,我運行了第5章的保持循環代碼:有一個Dog類實例和一個Cat類實例,它們彼此間都引用了對方。沒有其他引用再指向這兩個實例了,因此它們都存在洩漏問題。我通過Leaks追蹤模板來分析應用。Instruments檢測到了洩漏,甚至還繪製了圖表展示了錯誤的結構!

圖9-14:Instruments展示了保持循環

在最後這個示例中,我想知道是否可以縮短Diabelli』s Theme應用加載圖片的時間。我將目標設為了設備,因為只有真正的設備才能體會到速度的重要性並且需要進行度量。選擇Product→Profile。Instruments啟動,我選擇了Time Profiler追蹤模板。當應用在設備上隨Instruments啟動後,我不斷加載新圖片來執行這部分代碼。

在圖9-15中,我已經暫停了Instruments,看看圖上都有什麼。打開窗口下方的小三角,我可以鑽取到自己的代碼,這是由模塊名MomApp2所標識的(之所以叫這個名字是因為一開始是將這個應用作為我母親的生日禮物的)。

雙擊這一行可以看到自己代碼的執行時間(如圖9-16所示)。分析器所指出的對CGImageSourceCreateThumbnailAtIndex的調用引起了我的注意;此處消耗了大部分的CPU時間。該調用位於ImageIO框架中;它並不是我寫的代碼,因此我對其速度的提升無能為力。不過,我可以通過另外一種方式加載圖片;比如,以一些臨時的內存作為代碼,我可以將圖片全部加載進來並縮放。如果擔心速度問題,我可以花點時間做試驗。關鍵在於我現在知道了該如何做試驗。這只不過是Instruments所擅長的基於事實的數值分析的一個方面而已。