# 程序內容加載順序
1.啟動 dyld莉撇,將二進制文件初始化
2.ImageLoader 把二進制文件加載進內存
3.runtime 執(zhí)行 load_images 先慷,執(zhí)行所有的 load 方法
使用一個全局數組從含有 load 方法的根父類到自身置蜀,依次添加
使用另一個全局數組添加含有 load 方法的所有分類
依次執(zhí)行存儲的 load 方法填渠,父類 -> 自身 -> 分類
4.執(zhí)行自定義的 load 方法
對于加入運行期系統(tǒng)的類及分類钦听,必定會調用此方法椿争,且僅調用一次逾柿。
iOS會在應用程序啟動的時候調用load方法缀棍,在main函數之前調用
執(zhí)行子類的load方法前,會先執(zhí)行所有超類的load方法机错,順序為父類->子類->分類
在load方法中使用其他類是不安全的睦柴,因為會調用其他類的load方法,而如果關系復雜的話毡熏,就無法判斷出各個類的載入順序坦敌,類只有初始化完成后,類實例才能進行正常使用
load 方法不遵從繼承規(guī)則,如果類本身沒有實現load方法狱窘,那么系統(tǒng)就不會調用杜顺,不管父類有沒有實現(跟下文的initialize有明顯區(qū)別)
盡可能的精簡load方法,因為整個應用程序在執(zhí)行l(wèi)oad方法時會阻塞蘸炸,即躬络,程序會阻塞直到所有類的load方法執(zhí)行完畢,才會繼續(xù)
load 方法中最常用的就是方法交換method swizzling
## App啟動過程
解析Info.plist
? 加載相關信息搭儒,例如如閃屏
? 沙箱建立穷当、權限檢查
? Mach-O加載
? 如果是胖二進制文件,尋找合適當前CPU類別的部分
? 加載所有依賴的Mach-O文件(遞歸調用Mach-O加載的方法)
? 定位內部淹禾、外部指針引用馁菜,例如字符串、函數等
? 執(zhí)行聲明為attribute((constructor))的C函數
? 加載類擴展(Category)中的方法
? C++靜態(tài)對象加載铃岔、調用ObjC的 +load 函數
? 程序執(zhí)行
· 1.main函數
· 2.執(zhí)行UIApplicationMain函數
· 1.創(chuàng)建UIApplication對象
· 2.創(chuàng)建UIApplicationDelegate對象并復制
· 3.讀取配置文件info.plist汪疮,設置程序啟動的一些屬性,(關于info.plist的內容可網上搜索下)
· 4.創(chuàng)建應用程序的Main Runloop循環(huán)
· 3.UIApplicationDelegate對象開始處理監(jiān)聽到的事件
· 1.程序啟動成功之后毁习,首先調用application:didFinishLaunchingWithOptions:方法,
· 如果info.plist文件中配置了啟動storyboard文件名智嚷,則加載storyboard文件。
· 如果沒有配置纺且,則根據代碼來創(chuàng)建UIWindow--->UIWindow的rootViewController-->顯示
## App啟動優(yōu)化
App的啟動分為:熱啟動盏道、冷啟動。
一般我們說的啟動優(yōu)化 是指冷啟動
啟動優(yōu)化载碌,從2方面入手:Main函數之前摇天、Main函數之后。
Main函數之前 主要是由系統(tǒng)決定恐仑。
Main函數之后:由用戶的加在內容決定
在Main函數之前泉坐,有哪些是可以 做 優(yōu)化的:
1、庫的加載
系統(tǒng)庫經過優(yōu)化處理的裳仆,本身加載就 很快腕让。
自己倒入的庫: 蘋果給出的建議是不超過6個。如果超過6個歧斟,可以采用合并的方式纯丸。
2、減少不必要的類 静袖、資源圖片等觉鼻。
比如隨著版本更新迭代,有些類队橙、圖片等被棄用了的坠陈。
可以使用工具檢測沒有用到的類
這個操作相對來說優(yōu)化的成效不高萨惑。有人說 減少2w個類,啟動時間只少了800 毫秒仇矾。
3庸蔼、能不在Load里面做的操作,就不要在Load操作贮匕。
4姐仅、二進制重排
這個主要是正對binding階段的操作。
Main 之后的優(yōu)化
1刻盐、能懶加載的就懶加載
2掏膏、發(fā)貨CPU的性能(多線程初始化)
3、啟動階段的盡量不要用Xib敦锌、stroyboard馒疹。 Xib、storyboard都是需要進行xml解析供屉,相對純代碼來講,是比較耗時的溺蕉。
二進制重排
抖音團隊的一篇關于二進制重排
關于二進制重排伶丐,需要先了解虛擬內存和物理內存。
虛擬內存就是為了解決這些問題的疯特,先加載必須的信息哗魂,其他的信息當你用到的時候再在物理內存上去分配。
虛擬地址于物理地址 中間通過一張映射表(頁表)進行管理漓雅。由硬件mmu(CPU里的一個單元)來管理录别。
我們在Xcode里面打印出來的地址 都是虛擬地址,這個時候的地址是連續(xù)的邻吞。但是實際地址需要通過映射表(頁表)去尋址组题。 在物理地址上可能是不連續(xù)的,
物理內存是分頁的(在iOS設備 一頁16K抱冷,Mac 一頁4K)崔列。當App加載的時候,會將虛擬內存映射到物理內存
## 性能優(yōu)化
1.TableViewCell 復用
在cellForRowAtIndexPath:回調的時候只創(chuàng)建實例旺遮,快速返回cell赵讯,不綁定數據。在willDisplayCell: forRowAtIndexPath:的時候綁定數據(賦值)耿眉。
2.高度緩存
在tableView滑動時边翼,會不斷調用heightForRowAtIndexPath:,當cell高度需要自適應時鸣剪,每次回調都要計算高度组底,會導致 UI 卡頓丈积。為了避免重復無意義的計算,需要緩存高度斤寇。
3.盡量不要用JPEG的圖片桶癣,應當使用PNG圖片。
子線程預解碼(Decode)娘锁,主線程直接渲染牙寞。因為當image沒有Decode,直接賦值給imageView會進行一個Decode操作莫秆。
優(yōu)化圖片大小间雀,盡量不要動態(tài)縮放(contentMode)。
盡可能將多張圖片合成為一張進行顯示镊屎。
4.減少透明view
使用透明view會引起blending惹挟,在iOS的圖形處理中,blending主要指的是混合像素顏色的計算缝驳。最直觀的例子就是连锯,我們把兩個圖層疊加在一起,如果第一個圖層的透明的用狱,則最終像素的顏色計算需要將第二個圖層也考慮進來运怖。這一過程即為Blending。
5.減少使用圓角
6.減少離屏渲染
離屏渲染指的是在圖像在繪制到當前屏幕前夏伊,需要先進行一次渲染摇展,之后才繪制到當前屏幕。
OpenGL中溺忧,GPU屏幕渲染有以下兩種方式:
On-Screen
Rendering即當前屏幕渲染咏连,指的是GPU的渲染操作是在當前用于顯示的屏幕緩沖區(qū)中進行。
Off-Screen
Rendering即離屏渲染鲁森,指的是GPU在當前屏幕緩沖區(qū)以外新開辟一個緩沖區(qū)進行渲染操作祟滴。