app的啓動過程(三)

這是戴老師發佈的第三篇,正經發布的第一篇。看了1天之後我就想說,我要不仍是去賣人蔘吧,太難了!這之後我要是全學會了我有馬上辭職去阿里的衝動。固然了,我除了在學習裏面的知識,我還在想1個問題。架構

爲何他會我不會?app

這個問題的扯淡程度直逼他的答案的扯淡程度,我以爲我不會的緣由是由於很大一段時間我以爲學了沒用。按照文章的優化方法,咱們那個小破app啓動頂多能縮短個幾百ms,由於原本app就簡單。可是縮短個幾百ms對於1個app沒用對於技術有用麼?這要涉及到學習方法。dom

我本身總結的學習方法是這樣的:好比你要學一門新的語言,你要買1本基礎書。有人說基礎啥的你上網查不就得了?可是別忘了,你沒學過你連查啥都不知道。還有就是學基礎的時候別查的太深,這個階段以用爲主。等過了這個階段,開始查漏補缺,進行深刻進階。這也是我學習戴老師課程的緣由。因此縮短個幾百ms,可能用app的人感受不到,可是這個技術不理解,我看我下一章也不用看了。函數

正文開始,app的啓動過程學習

咱們首先將app分爲冷啓動和熱啓動,熱啓動顧名思義,人家都熱了,說明啓動一遍了,可能在後臺啥的,這個階段能作的事不多,咱們不研究。咱們從冷啓動開始說,冷啓動咱們又分爲三個階段優化

1. main()函數執行前。這個階段咱們主要有如下幾個部分(1)加載可執行二進制文件mach-o文件(昨天的查漏補缺一直就是針對的這個)(2)加載動態庫連接器dyld,dyld是個專門用來加載動態連接庫的庫。執行從d yld開始,dyld從可執行文件的依賴開始,遞歸加載全部的依賴動態連接庫。動態連接庫包括iOS用到的全部系統Framework,加載OCruntime用到的libObjc,系統級別的libSystem,例如libdispatch(GCD)和libsystem_blocks(Block),進行 rebase 指針調整和 bind 符號綁定 (3)Objc進行類的註冊,肯定方法的惟一性 (4)初始化執行load方法,attribute((constructor)) 修飾的函數,建立C++全局靜態變量。spa

好了,這些東西就足夠咱們研究一陣子的了。咱們先說一下什麼是Mach-o文件,mach-o就是Mach Object。官方給的Mach-o文件很是複雜,裏面有啥啥啥的看不懂的東西,就是已經細微到寄存器的東西,我實在研究不通。就只按我本身的理解來講,Mach-o文件其實就是一些文件的集合:裏面有二進制文件,類型爲Excutable,裏面還有動態庫文件dylib,裏面還有捆綁包,bundle包,一種特別的動態庫,只能在運行時運行。Framework文件,是包含資源或者頭文件的靜態庫或者動態庫。那麼mach-o文件在哪裏看呢,我找了半天就是沒找到。後來才知道,通常的framework裏面都有.o文件可是你是看不到的,你須要用一個叫MachOView的軟件打開它才能看見裏面的.o文件不然你看到的可能就是這樣的指針

這是百度人臉識別的SDK,反正我是沒找到什麼.o文件。可是咱們好像換一種方法看不到,能摸到:cdn

這樣咱們確實看到它是1個mach-o文件了哈,可是再深刻的我就沒有研究了。blog

下面咱們在研究下什麼叫rebase指針調整和bind符號綁定。首先咱們肯定一下這個是動做是誰作的。是dyld作的。dyld是什麼?動態庫鏈接器。怎麼樣連接動態庫?爲何要連接動態庫?由於加載了mach-o二進制文件後,動態庫是獨立的,dyld要將全部動態庫綁定起來。mach-o動態庫上面要寫上要綁定的動態庫的指針和數據,用來修正(fix-up),修正有兩種類型,一種叫rebasing,一種叫binding。爲何要修正呢?聽說在iOS4.3之前不須要修正,後來有了ASLR(address space layoutrandomization)的存在,可執行文件和動態連接庫在虛擬內存中的加載地址每次啓動都不固定,因此須要這2步來修復鏡像中的資源指針,來指向正確的地址。 rebase修復的是指向當前鏡像內部的資源指針; 而bind指向的是鏡像外部的資源指針。 第三點進行類的註冊優化起來就很明瞭,就是咱們儘量減小類的數量,就能夠減小加載時間。第四個,初始化執行load方法也很簡單就是少些+load()方法,attribute((constructor)) 修飾的函數調用就是1個函數能夠在main函數以前調用,有什麼做用還不清楚,我沒用過,如圖:

輸出爲:

C++全局變量就相似於這種,如圖:

2. main()函數執行後。main() 函數執行後的階段,指的是從 main() 函數到 appDelegate 的 didFinishLaunchingWithOptions方法裏首屏渲染相關方法執行完成。這裏面要寫的東西咱們你們就很熟悉了,通常就是初始化首屏架構,一些第三方的初始化,可是其中咱們應該區分開,哪些是首屏渲染以前應該寫的,哪些能夠在使用功能的時候纔開始。另外關於這個首屏初始化沒有1個固定的說法,有些人認爲到首頁viewDidAppear出現了纔算,有的人認爲走完了didFinishLaunchingWithOptions就算,看我的理解吧。

相關文章
相關標籤/搜索