# iOS基礎(chǔ) # App生命周期知識學(xué)習(xí)整理

做iOS開發(fā)日常不怎么涉及到這些內(nèi)容,但總會遇見相關(guān)的bug或者一些優(yōu)化需求。下面整理學(xué)習(xí)一些知識。

程序啟動過程發(fā)生了什么?

啟動后發(fā)生了什么?

程序啟動后的生命周期是怎么樣的?

如何優(yōu)化啟動時間?

App啟動過程

iOS開發(fā)中,main函數(shù)是我們熟知的程序啟動入口,但實際上并非真正意義上的入口,因為在我們運行程序,再到main方法被調(diào)用之間,程序已經(jīng)做了許許多多的事情,比如我們熟知的runtime的初始化就發(fā)生在main函數(shù)調(diào)用前,還有程序動態(tài)庫的加載鏈接也發(fā)生在這階段。

1、系統(tǒng)先讀取App的可執(zhí)行文件(Mach-O文件),獲取到dyld的路徑,并加載dyld(動態(tài)庫鏈接程序)。

2、dyld去初始化運行環(huán)境、開啟緩存策略、加載依賴庫、我們的可執(zhí)行文件、鏈接依賴庫,并調(diào)用每個依賴庫的初始化方法。

3、在上一步runtime被初始化,當所有的依賴庫初始化后,程序可執(zhí)行文件進行初始化,這個時候runtime會對項目中的所有類進行類結(jié)構(gòu)初始化,然后調(diào)用所有類的+load方法。

1、runtime初始化方法 _objc_init 中最后注冊了兩個通知:

map_images: 主要是在鏡像加載進內(nèi)容后對其二進制內(nèi)容進行解析,初始化里面的類結(jié)構(gòu)等

load_images: 主要是調(diào)用call_load_methods 按照繼承層次依次調(diào)用Class的 +load方法 然后是Category的+ load方法。(call_load_methods 調(diào)用load 是通過方法地址直接調(diào)用的load方法,并不是通過消息機制,這就是為什么分類中的load方法并不會覆蓋主類以及其他同主類的分類里的load 方法實現(xiàn)了。)

2、runtime 調(diào)用項目中所有的load方法時,所有的類的結(jié)構(gòu)已經(jīng)初始化了,此時在load方法中可以使用任何類創(chuàng)建實例并給他們發(fā)送消息。

4、最后dyld返回main函數(shù)地址,main函數(shù)被調(diào)用。

App啟動后

App啟動后執(zhí)行流程

main() -> UIApplicationMain() -> UIApplication 構(gòu)建、Appdelegate 構(gòu)建、info.plist文件加載

UIApplication -> runloop創(chuàng)建

Appdelegate(代理)  -> didFinishLaunchingWithOptions 函數(shù)執(zhí)行( window構(gòu)建、RootVC構(gòu)建)

app運行的五種狀態(tài)

ios app有5種狀態(tài),分別是:

1、Not running未運行:app沒啟動或被迫終止。

2、Inactive未激活:當前應(yīng)用正在前臺運行,但是并不接收事件(當前或許正在執(zhí)行其它代碼)。一般每當應(yīng)用要從一個狀態(tài)切換到另一個不同的狀態(tài)時,中途過渡會短暫停留在此狀態(tài)。唯一在此狀態(tài)停留時間比較長的情況是:當用戶鎖屏?xí)r,或者系統(tǒng)提示用戶去響應(yīng)某些(諸如電話來電、有未讀短信等)事件的時候。

3、Active激活:當前應(yīng)用正在前臺運行,并且接收事件。這是應(yīng)用正在前臺運行時所處的正常狀態(tài)。

4、Backgroud后臺:程序在后臺而且能執(zhí)行代碼,大多數(shù)程序進入這個狀態(tài)后會在在這個狀態(tài)上停留一會。時間到之后會進入掛起狀態(tài)(Suspended)。經(jīng)過特殊的請求后可以長期處于Backgroud狀態(tài)。

5、Suspended掛起:程序在后臺不能執(zhí)行代碼。系統(tǒng)會自動把程序變成這個狀態(tài)而且不會發(fā)出通知。當掛起時,程序還是停留在內(nèi)存中的,當系統(tǒng)內(nèi)存低時,系統(tǒng)就把掛起的程序清除掉,為前臺程序提供更多的內(nèi)存。

App的生命周期

application:didFinishLaunchingWithOptions:   這是程序啟動時調(diào)用的函數(shù)。

applicationDidBecomeActive:  應(yīng)用在準備進入前臺運行時執(zhí)行的函數(shù)。

applicationWillResignActive:   應(yīng)用當前正要從前臺運行狀態(tài)離開時執(zhí)行的函數(shù)。

applicationDidEnterBackground: 此時應(yīng)用處在background狀態(tài),并且沒有執(zhí)行任何代碼,未來將被掛起進入suspended狀態(tài)。

applicationWillEnterForeground:  當前應(yīng)用正從后臺移入前臺運行狀態(tài),但是當前還沒有到Active狀態(tài)時執(zhí)行的函數(shù)。

applicationWillTerminate:  當前應(yīng)用即將被終止,在終止前調(diào)用的函數(shù)。如果應(yīng)用當前處在suspended,此方法不會被調(diào)用。

啟動時間優(yōu)化

啟動時間

啟動時間是用戶點擊App圖標,到第一個界面展示的時間

啟動時間在小于400ms是最佳的,因為從點擊圖標到顯示Launch Screen,到Launch Screen消失這段時間是400ms。啟動時間不可以大于20s,否則會被系統(tǒng)殺掉。

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

Edit Scheme - Arguments - Environment Variables

冷啟動 和 熱啟動

如果你剛剛啟動過App,這時候App的啟動所需要的數(shù)據(jù)仍然在緩存中,再次啟動的時候稱為熱啟動。如果設(shè)備剛剛重啟,然后啟動App,這時候稱為冷啟動。

優(yōu)化啟動時間

用Time Profiler 檢查一遍自己的App。

main函數(shù)之前的優(yōu)化蘋果本身已經(jīng)處理了很好,一般而言,不再需要我們?nèi)フ{(diào)整,調(diào)整性價比也會比我們調(diào)整自己的代碼低很多,所以優(yōu)化啟動時間大部分是優(yōu)化我們自己寫的代碼。

優(yōu)化main函數(shù)之前的操作

動態(tài)庫加載優(yōu)化

加載系統(tǒng)的動態(tài)庫使很快的,因為可以緩存,而加載內(nèi)嵌的動態(tài)庫速度較慢。

所以,提高這一步的效率的關(guān)鍵是:減少我們自己的動態(tài)庫的數(shù)量。

之前公司進行項目模塊化的時候拆出來很多庫,pod一加載 30幾個pod,編譯都慢成狗,這種情況建議合并動態(tài)庫,比如公司內(nèi)部由私有Pod建立了如下動態(tài)庫:XXTableView, XXHUD, XXLabel,強烈建議合并成一個XXUIKit來提高加載速度。

runtime初始化優(yōu)化

合并Category和功能類似的類

刪除廢棄代碼

其他


+load 中少做swizzle 等操作

不要在 Initializers 創(chuàng)建線程等操作

多用swift 靜態(tài)分發(fā)

優(yōu)化我們自己的代碼

從main函數(shù)開始執(zhí)行,到你的第一個界面顯示,這期間一般會做的事情:

1、執(zhí)行AppDelegate的代理方法,主要是didFinishLaunchingWithOptions

2、初始化Window,初始化基礎(chǔ)的ViewController結(jié)構(gòu)(一般是UINavigationController+UITabViewController)

3、獲取數(shù)據(jù)(Local DB/Network),展示給用戶。

處理方向:

AppDelegate 中的方法

didFinishLaunchingWithOptions 方法


applicationDidBecomeActive 方法


能延遲初始化的盡量延遲初始化,不能延遲初始化的盡量放到后臺初始化。

第一個頁面展示

延遲初始化那些不必要的 UIViewController

以上兩個地方不使用大量占用主線程資源的操作,數(shù)據(jù)獲取解析等放在異步處理。

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

相關(guān)閱讀更多精彩內(nèi)容

  • 1 dyld 1.1 dyld簡介 在iOS系統(tǒng)中,幾乎所有的程序都會用到動態(tài)庫,而動態(tài)庫在加載的時候都需要用d...
    Kevin_Junbaozi閱讀 12,562評論 4 44
  • 背景 一個項目做的時間長了,啟動流程往往容易雜亂,庫也用的越來越多,APP的啟動時間也會慢慢變長。本次將針對iOS...
    醬油瓶2閱讀 3,636評論 0 12
  • iOS 系統(tǒng)架構(gòu) Mac系統(tǒng)是基于Unix內(nèi)核的圖形化操作系統(tǒng),Mac OS 和 iOS 系統(tǒng)架構(gòu)的對比分析發(fā)現(xiàn),...
    一個人在路上走下去閱讀 21,838評論 11 198
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 13,899評論 2 59
  • 【詩和遠方】 人生歸去來,兜兜轉(zhuǎn)轉(zhuǎn) 才發(fā)現(xiàn),遠方都很美,曾經(jīng)才是夢 誰不想面朝大海彈琴寫作 誰不想春暖花開養(yǎng)花品茶...
    枕泉閱讀 219評論 0 1

友情鏈接更多精彩內(nèi)容