隨着iOS項目愈來愈大,啓動時間也會變得愈來愈慢,咱們如何來對app的啓動時間來進行優化,給用戶一個更好的體驗呢?xcode
應用啓動分爲冷啓動和熱啓動安全
- 冷啓動是指內存中不存在與應用相關的數據,須要從硬盤時將應用的數據載入到內存中;這個過程是由系統決定的,平時咱們把應用殺死,而後立刻啓動,此時內存中的應用相關的數據不會立刻被清除,因此這時候的啓動不是冷啓動;
- 熱啓動是指內存中還存留着應用相關的數據,應用運行所須要的數據不須要所有從硬盤中載入內存。
咱們能夠經過設置環境變量來起到監控應用啓動時間的目的,有關環境變量的設置,請參考Xcode環境變量markdown
咱們設置環境變量DYLD_PRINT_STATISTICS
,運行工程,打印應用啓動時的時間消耗狀況: 多線程
打印出應用啓動時間以下: app
咱們以main函數爲分隔點,將應該啓動時間優化分爲main函數以前和main函數以後,這裏所打印的pre-main time就是main函數以前的耗時。函數
dylib loading time
:動態庫的載入耗時,蘋果建議項目中自定義的動態庫最好不要超過6個動態庫,若是超過了6個要考慮動態庫合併;rebase/binding time
:偏移修正
(rebase)和符號綁定
(binding)的耗時;偏移修正是一個安全機制--ASLR
,原理是生成一個隨機值,加到應用內存地址的前面,來起到方法、函數的地址隨機的目的,解決安全問題.全部的方法、函數和數據的內存地址都會在原有的真實地址上加上這個隨機值
,而且每次啓動的時候這個隨機值是不一樣的,這樣別人就無法拿到方法、函數或數據的真實地址了;符號綁定是指將方法名與方法的實現,即sel和IMP的綁定。ObjC setup time
:Object-C類的註冊的耗時;不權威統計,每增長20000個類,這個時間增長800ms;減小類的數量能夠減小啓動耗時;initializer time
:load方法和構造方法的耗時.因此項目中要儘可能減小重寫load 方法,將load方法的操做放在initialization中.
以上就是main函數以前的啓動耗時說明及相關優化方案;post
對於main函數以後的啓動耗時,咱們能夠經過代碼的方式進行監控,好比,在main函數中記錄一個時間,到第一個界面顯示的viewDidLoad方法中記錄一個時間,兩個時間的差值就是main函數以後的啓動耗時.因爲main函數以後的耗時須要根據不一樣的項目來區分,不能一律而論,這裏提供幾個優化的建議優化
- 減小數據的加載,最好使用懶加載,如一個第三文庫的加載;
- 將項目中再也不使用的類和方法去掉;
- 使用多線程技術加載數據,充分利用cpu的資源;
- 啓動時刻的界面,不要使用storyboard或xib,儘可能使用純代碼,由於storyboard或xib有一步代碼轉換的操做,也是會耗時的。
應用程序在運行時,使用的是虛擬內存與物理內存相結合的方法加載數據的;虛擬內存是分頁管理的,當使用到某一頁虛擬內存的數據時,須要將對應的真實數據加載到物理內存中,將虛擬內存與物理內存以前造成一個映射關係,這個操做稱爲缺頁異常(page fault),這個操做是需耗時的。spa
查看iOS應用的載入數據的順序,咱們能夠經過設置Write Link Map File
爲yes,來查看應用數據加載的順序 線程
clean
一下工程,而後command+B
編繹一下工程,來到Products的xx.app
目錄下
再來到以下目錄下
找到以下文件
打開此文件Demo-LinkMap-normal-x86_64.txt
這裏的順序就是應用數據加載的順序,這裏的順序是由下以兩個因素決定的
按文件順序從上到下
按文件中的方法的順序從上到下
驗證一下此文件的順序就是實際的載入順序,能夠經過修改文件或方法的順序,而後從新編繹後查看link map文件的方法順序是否改變。
因爲咱們在應用在啓動時可能只須要某些文件中的某些方法,而按照實際的方法載入順序,在應用啓動時會由於page fault
的存在,就須要載入大量的用不到的數據,形成了大量的時間消耗,爲此咱們只須要在應用啓動時只載入啓動時須要的方法就能夠了,其實的數據能夠後續載入;爲此咱們能夠經過建立一個.order
文件來修改方法或函數的加載順序.
打開hank.order
文件,查看如下幾個方法的順序
將此文件配置到對應的xcode工程中
clean後從新編繹,查看Demo-LinkMap-normal-x86_64
文件
這樣咱們就成功的修改了方法或函數的加載順序,因此咱們只須要知道應用啓動時執行了哪些方法,將他們排序好,放在.order文件中,就能夠在應用啓動時,只加載了本身須要的數據,減小了page fault的次數,從而減小了啓動耗時。
那麼如何知道應用啓動時執行了哪些方法呢?請看Hook一切的終極武器--Clang插樁