635,iOS啟動流程(面試點:App啟動主要包括三個階段:減少動態(tài)庫數(shù)量,可以合并動態(tài)庫 減少無用的方法和類,合并分類 減少 在load方法,試著用Initialize替代 減少atri...

關于mach-o
mach-O文件為Mach Object文件格式的縮寫,它是一種用于可執(zhí)行文件,目標代碼,動態(tài)庫,內核轉儲的文件格式。
常見的有以下形式:

  • Executable 可執(zhí)行文件
  • Dylib動態(tài)庫和Framework動態(tài)庫,對應頭文件和資源文件集合

Apple可執(zhí)行文件格式幾乎都是mach-o;

關于更多mach-o ,可參考Mac OS X ABI Mach-O File Format Reference

關于mach-o數(shù)據(jù)結構,可參考Mac本地路徑下的/usr/include/mach-o源碼。

為了直觀看出mach-o相關信息,可以使用三方工具MachOView

MachOView下載

編譯好的工程很老了,建議下載源碼自己運行使用。

MachOView源碼地址

關于安裝源碼啟動報錯,可參看別人已經寫好的說明,我這邊就不多說了。

mach-o文件分析工具 MachOview探究

這里我用MachOView工具打開了我本地的一個動態(tài)庫。如圖:

image.png

關于 dyld

dyld(the dynamic link editor)是蘋果的動態(tài)鏈接器,在系統(tǒng)內核做好程序準備工作之后,交由dyld負責余下的工作。它代碼是開源的。源碼地址
在App啟動時它就負責加載mach-o文件。
關于 dyld詳細解析說明,可參考dyld詳解

App 具體啟動流程

App啟動一般分兩種冷啟動和熱啟動:

  • 冷啟動是指, App 點擊啟動前,它的進程不在系統(tǒng)里,需要系統(tǒng)新創(chuàng)建一個進程分配給它啟動的情況。這是一次完整的啟動過程。

  • 熱啟動是指 ,App 在冷啟動后用戶將 App 退后臺,在App 的進程還在系統(tǒng)緩存的情況下,用戶重新啟動進入 App。

這里我們說的主要是冷啟動。

App啟動主要包括三個階段:

1: main()函數(shù)執(zhí)行前

這里就主要是dyld加載mach-o文件了

加載步驟主要分以下幾步:

  • 設置運行環(huán)境

主要設置運行參數(shù),環(huán)境變量之類的??梢栽賦code的 Product->Scheme -> EditScheme,配置環(huán)境變量DYLD_PRINT_OPTSDYLD_PRINT_ENV,通過xcode打印dyld加載各種運行參數(shù)和環(huán)境變量。

image.png
  • 加載共享緩存

如果共享緩存已加載就不在額外處理。

  • 加載可執(zhí)行文件

  • 主程序的Mach-O加載進內存,并實例化一個ImageLoader。
    ImageLoader是抽象類,其子類負責把Mach-O文件實例化。

  • 加載動態(tài)庫

    會先從共享緩存中搜索

  • 鏈接主程序,進行 rebase 指針調整
    將實例化后的主程序進行動態(tài)修正,讓二進制變?yōu)榭烧?zhí)行的狀態(tài)。
    Rebase 修正內部(指向當前mach-o文件)的指針指向.

  • Bind 修正外部指針指向
    包括鏈接插入的動態(tài)庫,執(zhí)行弱符號綁定。

  • 運行時Runtime 初始化
    相關類注冊,分類注冊,方法唯一性檢查.
    我們可以通過先加符號斷點 斷在_objc_init,就可清晰看到dyld執(zhí)行到runtime初始化
    之前的調用了。

image.png
image.png

我們可以看到:
棧底的dyldbootstrap::start()方法,繼而調用了dyld::_main()方法,再到ImageLoader,再到objc_init

  • 其他必要的初始化

  • +load方法,

  • C/C++靜態(tài)初始化對象和標記為attribute(constructor)的方法

2:main()函數(shù)執(zhí)行后

從main()函數(shù)執(zhí)行開始,到appDelegate 的 didFinishLaunchion里首屏渲染相關方法執(zhí)行完成。

3:首屏渲染完成之后

其他業(yè)務模塊相關代碼初始化,文件處理,業(yè)務監(jiān)聽等等。

App啟動時間優(yōu)化

在Xcode中,可以通過設置環(huán)境變量來查看App的啟動時間,DYLD_PRINT_STATISTICSDYLD_PRINT_STATISTICS_DETAILS

通過了解App啟動流程,我們可以做以下優(yōu)化

main()函數(shù)執(zhí)行前:

  • 減少動態(tài)庫數(shù)量,可以合并動態(tài)庫

  • 減少無用的方法和類,合并分類

  • 減少 在load方法,試著用Initialize替代

  • 減少atribute((constructor))的使用,控制全局變量數(shù)量

main()函數(shù)之后:

對業(yè)務進行模塊化處理,非首屏渲染業(yè)務應當盡量放到首屏渲染之后處理。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • sdk開發(fā)筆記基礎: 說到動態(tài)庫,就不得不提靜態(tài)庫。靜態(tài)庫可以看做是一個具有特定功能的代碼塊,如果app中引用了靜...
    F麥子閱讀 6,688評論 0 17
  • 如果你經常困惑 iOS 開發(fā)中的靜態(tài)庫和動態(tài)庫的作用與區(qū)別, 那么這篇文章可以為你解惑 靜態(tài)庫 (Static L...
    閃耀旅途閱讀 2,183評論 1 2
  • 前言 啟動時間是衡量應用品質的重要指標。 本文首先會從原理上出發(fā),講解iOS系統(tǒng)是如何啟動App的,然后從main...
    荒漠現(xiàn)甘泉閱讀 982評論 0 2
  • 本文首先會從原理上出發(fā),講解iOS系統(tǒng)是如何啟動APP的,然后從main函數(shù)之前和main函數(shù)之后倆個角度去分析如...
    ElegantLiar閱讀 1,009評論 0 10
  • 一、認識庫 庫是一種共享程序代碼的方式,在計算機科學中,庫(英語:library)是用于開發(fā)軟件的子程序集合。庫和...
    KinKen閱讀 3,781評論 0 8

友情鏈接更多精彩內容