iOS應用啟動流程分析之dyld過程初探
theme: fancy highlight: agate
前言:作為一個開發者,如果你熟悉很多語言的開發,你會發現大部分語言的一個共同點,main函式。我們都是從main函式開始,去關注程式的編寫、編譯和執行過程。main函式之前,系統有沒有做一些其他的工作,做了哪些工作呢,一起來看看?
一、應用啟動分析
1、程式從編寫到執行的過程
1、程式碼怎麼載入到記憶體?
2、靜態庫、動態庫怎麼載入到記憶體?
3、objc_init -> objc 在哪裡執行的?
我們可以想一下以上的過程是怎麼發生的,各個環節都是怎麼載入到記憶體的?
2、靜態庫和動態庫
我們經常在專案中使用靜態庫和動態庫,其中系統提供的UIKit,Foundation庫,WebKit庫等等,這些是動態庫,比如我們經常使用的自定義的靜態Framework,.a檔案,就是屬於靜態庫。那麼,靜態庫和動態庫是怎麼區分的?
- 動態庫形式:.dylib和.framework
- 靜態庫形式:.a和.framework
如上圖所示,我們分析:
1、靜態庫:連結時,靜態庫會被完整地複製到可執行檔案中,被多次使用就有多份冗餘拷貝
2、動態庫:連結時不復制,程式執行時由系統動態載入到記憶體,供程式呼叫,系統只加載一次,多個程式共用,節省記憶體
但是,系統的動態庫怎麼載入到記憶體呢?通過什麼方式?這裡就用到了一個工具dyld動態連結器。
3、動態連結器
3.1 動態連結器的工作過程
上面是dyld的載入工作流程圖,通過它主要進行了動態庫的註冊和動態庫的載入過程。
二、dyld過程初探
- 通過上面原理的整體分析後,我們接下來就進行應用程式程式碼執行邏輯的分析
在main函式的入口位置,加上斷點,執行後程序停在斷點位置,經過堆疊列印(bt為lldb堆疊列印命令),發現程式是崩潰在了lldb中,這裡我們並不能獲取更多資訊去跟蹤。
於是,我們通過程式設計經驗,想到了在程式執行main函式之前,會提前執行load函式的載入,那麼就做一下嘗試,在ViewController中假如load函式,並新增斷點,執行程式。
結果很順利,我們斷點停在了ViewController的load方法,通過堆疊列印,發現了關於dyld的一系列函式過程。下面就引出我們探究的主題:dyld(動態連結器),我們的函式追蹤,也將按照這樣一個順序去進行!
1、dyld簡介
dyld(the dynamic link editor)是蘋果的動態連結器,是蘋果作業系統一個重要組成部分,在系統核心做好程式準備工作之後,交由dyld負責餘下的工作。而且它是開源的,任何人可以通過蘋果官網下載它的原始碼來閱讀理解它的運作方式,瞭解系統載入動態庫的細節。
2、dyld的原始碼
這裡我們選擇最新的版本進行研究,技術嘛,總要與時俱進,下載完這些,先不急,先來一個蘋果的官方影片介紹,關於dyld2,到dyld3過程的更新、特性,然後我們在下一章介紹 dyld 的探究過程。
3、蘋果官方關於dyld的介紹影片
App Startup Time: Past, Present, and Future http://developer.apple.com/videos/play/wwdc2017/413/
三、總結
我們這裡介紹了應用啟動過程的大概過程分析,主要有:
1、動態庫與靜態庫的概念和理解
2、dyld的概念和連結過程解析
3、我們是如何知道程式是在main函式之前進入了dyld
關於dyld的詳細執行過程,下一節單獨講解!
連結:iOS應用啟動流程分析之dyld原始碼解析
🌺更多內容期待與你一起分享,喜歡的話,點個贊點個關注,持續為您創造好的內容。