【學(xué)習(xí)總結(jié)】02 | App 啟動速度怎么做優(yōu)化與監(jiān)控?

1、前言

首先,我認(rèn)為學(xué)習(xí)總結(jié),要有所總,所結(jié),就是有歸納后,能用自己的話告訴別人!有所結(jié),就是有所收獲輸出,一般我認(rèn)為是思維導(dǎo)圖,所以,每篇文章前,我都會先給出文章的腦圖:

iOS開發(fā)高手課-02-App啟動速度怎么做優(yōu)化與監(jiān)控?.png

2、正文

注意,本系列總結(jié)不會引用或提供原課程文章所有的內(nèi)容或代碼,只會作出思維導(dǎo)圖,需要學(xué)習(xí)可購買課程 《iOS開發(fā)高手課 - 極客時間》

本文作為第一篇,腦圖中包含了一些學(xué)習(xí)的方法論,這里就不展開了,具體可以查看 如何建立你自己的開發(fā)知識體系 | iHTCboy's blog

學(xué)習(xí)原則

授人以魚不如授人以漁

就想學(xué)習(xí)英語一樣,每一個字母都認(rèn)識,但是串聯(lián)起來就不認(rèn)識了。學(xué)習(xí)也一樣,可能整篇文章大家都看懂了,但是對于其中的詞語或句子,可能是不懂的,比如,rebase 指針、attribute((constructor))selector 唯一性檢查、動態(tài)庫加載、ReactiveCocoa框架、抓取主線程調(diào)用棧、Mach-O、lazy 和 non-lazy 符號、rebind_symbol、等。或者,整篇文章都沒有看懂,但是每個字都認(rèn)識。

第一種情況,對于不認(rèn)識的關(guān)鍵字,在搜索引擎就能找到很多,只能說是懶或恐懼心態(tài),讓你永遠(yuǎn)不去了解。第二種情況,一般多見于是抽象的文章,比如項目架構(gòu)、編程思想等,大家都懂 MVC/MVVM,就是說不出懂什么的感覺,這種情況,還是建議多廣義的學(xué)習(xí),更多的實踐,很多東西,還是較難做到言傳,只能意會!

還有一種情況,我認(rèn)為就是文章大家都看懂了,也沒有什么疑問,但是忽略了一個面的概念,把問題想太簡單,不會把知識點串聯(lián)起來,不會觸類旁通、融會貫通。舉個例子,做過開發(fā)的都應(yīng)該知道單例模式,如果不知道,搜索引擎都能搜索出一堆教程,并且介紹了來由,用途等,大家就知了知了。操作系統(tǒng)任務(wù)管理器、回收站、文件系統(tǒng)是不是一個單例?數(shù)據(jù)庫連接池呢?生活中的例子,比如主席、CTO,對一個國家或一個公司,都是唯一的。

所以,第三種情況,目前來看大多數(shù)人看文章學(xué)習(xí)都達(dá)不到的層次,需要借助大量的閱讀或別人的傳授或指點,才能悟出來。所以,這就是我要說的,授人以魚不如授人以漁,盡自己最大的已知學(xué)習(xí)和分享,這是一件快樂的事~

啟動

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

  • 熱啟動
    App 在冷啟動后用戶將 App 退后臺,在 App 的進(jìn)程還在系統(tǒng)里的情況下,用戶重新啟動進(jìn)入 App 的過程,這個過程做的事情非常少。

文章中簡單的提到了冷啟動熱啟動??赡艽蠹乙彩且豢炊^。這個啟動其實是很重要的概念,不知道大家有沒有留意,汽車發(fā)動機(jī)的冷啟動和熱啟動電腦的冷啟動和熱啟動?那么,手機(jī)是不是也有冷啟動和熱啟動?iOS有冷啟動和熱啟動,那么Android是不是也有冷啟動和熱啟動?那么App有冷啟動和熱啟動,那么微信的小程序是不是也有冷啟動和熱啟動?

答案是肯定的!它們都有!為什么呢???似乎所有的系統(tǒng)都有冷啟動和熱啟動!那么,冷啟動和熱啟動,那么對汽車的傷害更大嗎?冷啟動和熱啟動那個對性能損耗(消耗)更大呢?答案也是肯定的,是冷啟動!

我是希望通過這個例子,讓大家更加明白,一個簡單的概念,可能很普通,但是一定不要放過!那么,到這里,針對App 啟動速度怎么做優(yōu)化,冷啟動和熱啟動的重要性是不是自然而然就出來了,我們應(yīng)該關(guān)注 App的冷啟動和熱啟動,減少冷啟動,盡量讓App在后臺時能通過熱啟動打開。,怎么理解呢?對于 iOS,系統(tǒng)嚴(yán)管管控手機(jī)的內(nèi)存,當(dāng)發(fā)現(xiàn)內(nèi)存不足時,系統(tǒng)會全局發(fā)通知,讓大家把不要的內(nèi)存釋放出來,如果大家都不釋放,后臺的應(yīng)用就會被干掉,當(dāng)然前臺的應(yīng)用如果占用內(nèi)存超過閾值的話也會被干掉(kill)。所以,解決 App 啟動速度怎么做優(yōu)化,我們在寫代碼時,能注意到 App 內(nèi)存使用情況,節(jié)省內(nèi)存空間,減少不必要的內(nèi)存創(chuàng)建,及時的釋放內(nèi)存等,都是對優(yōu)化起到舉足輕重的作用。

以上,就是冷啟動和熱啟動,希望大家能感受到我一直說的觸類旁通、融會貫通的理念。

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

  1. main() 函數(shù)執(zhí)行前
  2. main() 函數(shù)執(zhí)行后
  3. 首屏渲染完成后

文章中說的內(nèi)容,這里就不打算詳細(xì)展開,簡單的看本文的思維導(dǎo)圖就可以,另外,文章中的很多細(xì)節(jié)的內(nèi)容,在后續(xù)的篇章中會慢慢的介紹,這里就不展開,否則說不完事,大家感興趣的,可以提前自行搜索,網(wǎng)絡(luò)上真的都有了!本文需要提的是,解答一下前面說的幾個有意思的問題

1、 +load() 方法和 +initialize() 方法

+load() 方法和 +initialize() 方法,大家都需要了解它們的區(qū)別和特性,這樣才能更好的做性能優(yōu)化。這里不作詳細(xì)介紹,網(wǎng)絡(luò)上能找到的,我這里不都不會說,除非值得注意的內(nèi)容。

2、 attribute((constructor)) 修飾的函數(shù)的調(diào)用

這個是C語言的函數(shù)屬性,有2種類型:__attribute__((constructor))__attribute__((destructor))

1)函數(shù)屬性功能

`__attribute__ ((constructor))`:會使函數(shù)在 `main()函數(shù)`之前執(zhí)行

`__attribute__ ((destructor))`:會使函數(shù)在 `main()函數(shù)`之后執(zhí)行

2)功能范圍

函數(shù)屬性`__attribute__((constructor))`和`__attribute__((destructor))`在可執(zhí)行文件或者庫文件里都可以生效


3)與全局變量比較

全局變量對象的構(gòu)造函數(shù)和析構(gòu)函數(shù)分別在`__attribute__((constructor))`和`__attribute__((destructor))`標(biāo)志的函數(shù)之前調(diào)用。

4)PRIORITY 優(yōu)先級

```
__attribute__((constructor(PRIORITY)))
__attribute__((destructor(PRIORITY)))
```

`__attribute__((constructor))` 按照優(yōu)先級小到大執(zhí)行,`__attribute__((destructor(PRIORITY)))` 則是從大到小執(zhí)行。

注意:
1、可執(zhí)行程序或庫文件都可以使用此屬性修飾函數(shù)
2、同一個可執(zhí)行程序或庫文件允許多個函數(shù)被修飾,執(zhí)行順序由代碼編寫順序或編譯鏈接順序有關(guān)

引用來源:函數(shù)屬性attribute((constructor))和attribute((destructor)) - tianmo2010的專欄

3、objc_msgSend 方法和 hook 內(nèi)容

hook的概率在很多的語言都有,因為安全和越獄等,針對 iOS 的 hook 網(wǎng)上也非常多,這里也不詳細(xì)說了,后面的章節(jié)如果有相關(guān)安全的在說吧。相信大家網(wǎng)絡(luò)上一定能找到很多資料!

4、怎樣獲取主線程調(diào)用棧?

相信有好奇心的同學(xué),在閱讀文章時,一定對怎樣獲取主線程調(diào)用棧的問題產(chǎn)生興趣,但可能如果之前沒有接觸過,一定覺得太難了!根本找不到方向或者感覺!但是,你仔細(xì)想想,是不是真的這么難?沒有方向?其實并不是,只要搜索一下,網(wǎng)絡(luò)上也是一堆一堆的。當(dāng)然,你想通過一篇文章就掌握所有這些相關(guān)的知識,那可能不太現(xiàn)實!你一定要明白,不勞而獲永遠(yuǎn)是獲得最少的!,所以,還是要靠自己努力,另外,后續(xù)的章節(jié)還會有這方面的深入知識,到時候在解答吧。希望大家能利用自己的學(xué)習(xí)能力,習(xí)得不亦樂乎!

5、監(jiān)控耗時和耗時統(tǒng)計

這個問題也值得大家注意,后續(xù)章節(jié)在一起討論。

6、源碼閱讀

蘋果公司已經(jīng)開源了 Objective-C 的運(yùn)行時代碼。你可以在蘋果公司的開源網(wǎng)站,找到 objc_msgSend的源碼

Facebook 開源了一個hook庫,可以在 iOS 上運(yùn)行的 Mach-O 二進(jìn)制文件中動態(tài)地重新綁定符號,這個庫叫 fishhook。

針對這種源碼,大多數(shù)人一定說,我看不懂!我看不懂!我看不懂!

這個,與下面這個問題相似,一起來回答吧

7、C語言、匯編語言 看不懂?!

看不懂?看不懂?看不懂?

有沒有發(fā)現(xiàn),我們小時候也不懂中文,現(xiàn)在怎么就看懂了呢!學(xué)啊!學(xué)啊!學(xué)?。?/p>

怎么學(xué)? 從入門到放棄??!怎么入門?

網(wǎng)絡(luò)上有很多優(yōu)秀的資源,大家如果真的感興趣,一定要主動去了解,一味地抗拒永遠(yuǎn)不會得到結(jié)果和答案。匯編語言入門教程 - 阮一峰的網(wǎng)絡(luò)日志 ,匯編語言入門學(xué)習(xí)就是這樣簡單,沒有看不懂,只有不看懂!

人生苦短,我們努力吧~

8、其它問題

其它的還有很多問題,這里就不一一指出,比如 Swift 有 main 函數(shù)嗎?希望大家 多疑問,多思考,多總結(jié)!,這樣成長更快啦~

3、總結(jié)

回到本文的主題,“App 啟動速度怎么做優(yōu)化與監(jiān)控?”,優(yōu)化,不知道大家是否還記得之前的第一篇文章說到的,不記得的可以回去看看。監(jiān)控的話,這里沒有詳細(xì)提到,因為性能監(jiān)控只是監(jiān)控系統(tǒng)的一小部分,后面的章節(jié)在細(xì)節(jié)展開吧。

這里先給出一個大綱,關(guān)于開發(fā)相關(guān)的工程優(yōu)化,因為這也是我們從 《iOS開發(fā)高手課 - 極客時間》 來,我們要干什么?到那里去呢?

  • 可以做什么?
  1. 工程優(yōu)化:代碼、規(guī)范、性能、AOP、日志
  2. 工程監(jiān)控:耗時、內(nèi)存、網(wǎng)絡(luò)、卡頓、崩潰、瘦身、耗電
  3. 工程效率:響應(yīng)式框架、函數(shù)式編程、APM、監(jiān)控系統(tǒng)
  4. 技術(shù)深研:RN、Flutter、小程序、動態(tài)化

很多知識點,大家現(xiàn)在看到這篇文章感覺一氣呵成,水到渠成的樣子,但是其實是一點一點的思考和觸想,可能有一個概念很久之前就有,但是怎么把這些知識串聯(lián)一起,確實是需要非常深厚的功能,才能做到。所以,本次系列,我只能說盡量自己的力量,因為我相信不管是后來者,還是以后的我,都一定超越現(xiàn)在的我!,所以,如果未來可以,可以在重寫此系列,也是一件令人愉快的事!

注:更多關(guān)于 iOS 開發(fā)和程序開發(fā)相關(guān)的內(nèi)容,可以查看此系列,目前還在連載中 【學(xué)習(xí)總結(jié)】iOS開發(fā)高手課 -- (連載中)| iHTCboy's blog,以上,希望對你有用!

參考

WWDC:

Article:


  • 如有侵權(quán),聯(lián)系必刪!
  • 如有不正確的地方,歡迎指導(dǎo)!
  • 如有疑問,歡迎在評論區(qū)一起討論!


注:本文首發(fā)于 iHTCboy's blog,如若轉(zhuǎn)載,請注來源

最后編輯于
?著作權(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ù)。

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