像C++,Objective C都是編譯語言袱衷。編譯語言在執(zhí)行的時候,必須先通過編譯器生成機器碼笑窜,機器碼可以直接在CPU上執(zhí)行致燥,所以執(zhí)行效率較高。
像JavaScript,Python都是直譯式語言排截。直譯式語言不需要經(jīng)過編譯的過程嫌蚤,而是在執(zhí)行的時候通過一個中間的解釋器將代碼解釋為CPU可以執(zhí)行的代碼辐益。所以,較編譯語言來說脱吱,直譯式語言效率低一些智政,但是編寫的更靈活。
iOS開發(fā)目前的常用語言是:Objective和Swift箱蝠。二者都是編譯語言续捂,換句話說都是需要編譯才能執(zhí)行的。二者的編譯都是依賴于Clang + LLVM.
基本的編譯過程大概分為四個步驟:
1.預(yù)處理(Pre-process):把宏替換宦搬,刪除注釋牙瓢,展開頭文件,產(chǎn)生.i文件间校。
2.編譯(Compliling):把之前的.i文件轉(zhuǎn)換成匯編語言矾克,產(chǎn)生.s文件。
3.匯編(Asembly):把匯編語言文件轉(zhuǎn)換為機器碼文件憔足,產(chǎn)生.o文件胁附。
4.鏈接(Link):對.o文件中的對于其他的庫的引用的地方進行引用,生成最后的可執(zhí)行文件(同時也包括多個.o文件進行 link)滓彰。
在 xcode 中可以通過?Build phases,Build settings以及?Build rules來進行控制控妻。
Build phases主要是用來控制從源文件到可執(zhí)行文件的整個過程的,所以應(yīng)該說是面向源文件的揭绑,包括編譯哪些文件弓候,以及在編譯過程中執(zhí)行一些自定義的腳本什么的。
Build rules主要是用來控制如何編譯某種類型的源文件的洗做,假如說相對某種類型的原文件進行特定的編譯弓叛,那么就應(yīng)該在這里進行編輯了彰居。同時這里也會大量的運用一些 xcode 中的環(huán)境變量诚纸,完整的官方文檔在這里:Build Settings Reference
Build settings則是對編譯工作的細節(jié)進行設(shè)定,在這個窗口里可以看見大量的設(shè)置選項陈惰,從編譯到打包再到代碼簽名都有畦徘,這里要注意 settings 的 section 分類,同時一般通過右側(cè)的 inspector 就可以很好的理解選項的意義了抬闯。
最后井辆,要說一下我們的工程文件.pbxproj,以上的所有的這些選項都保存在這個文件中。當(dāng)然也包括 target 的信息溶握,項目所有文件的信息杯缺,這個文件是一個文本文件,可以用文本編輯器打開睡榆。里頭的內(nèi)容基本是可讀性比較強的萍肆∨塾埽基本的思路很面向?qū)ο螅總€東西都有屬性塘揣,如果屬性是另一個對象包雀,值就是那個對象的一個『引用』,就是一串?dāng)?shù)字(唯一的)作為表示亲铡。每個對象都有這樣的引用才写。
不管是OC還是Swift,都是采用Clang作為編譯器前端奖蔓,LLVM(Low level vritual machine)作為編譯器后端.
1.編譯器前端
編譯器前端的任務(wù)是進行:語法分析赞草,語義分析,生成中間代碼(intermediate representation )锭硼。在這個過程中房资,會進行類型檢查,如果發(fā)現(xiàn)錯誤或者警告會標注出來在哪一行檀头。
2.編譯器后端
編譯器后端會進行機器無關(guān)的代碼優(yōu)化轰异,生成機器語言,并且進行機器相關(guān)的代碼優(yōu)化暑始。iOS的編譯過程搭独,后端的處理如下
LVVM優(yōu)化器會進行BitCode的生成,鏈接期優(yōu)化等等廊镜。
LLVM機器碼生成器會針對不同的架構(gòu)牙肝,比如arm64等生成不同的機器碼。
執(zhí)行一次XCode build的流程
·? 編譯信息寫入輔助文件嗤朴,創(chuàng)建編譯后的文件架構(gòu)(name.app)
· 處理文件打包信息配椭,例如在debug環(huán)境下
Entitlements:{
? ????? "application-identifier" = "app的bundleid";? ? "aps-environment" = development;
????}
·?執(zhí)行CocoaPod編譯前腳本?
? ??例如對于使用CocoaPod的工程會執(zhí)行CheckPods Manifest.lock
·?編譯各個.m文件,使用CompileC和clang命令雹姊。
· 鏈接需要的Framework股缸,例如Foundation.framework,AFNetworking.framework,ALiPay.fframework
·編譯xib文件
·拷貝xib,圖片等資源文件到結(jié)果目錄
·編譯ImageAssets
·處理info.plist
·??執(zhí)行CocoaPod腳本
·拷貝Swift標準庫
·創(chuàng)建.app文件和對其簽名
如何提高項目編譯速度
一.查看編譯時間
對于XCode 8吱雏,關(guān)閉XCode敦姻,終端輸入以下指令
$ defaults writecom.apple.dt.XcodeShowBuildOperationDuration YES
然后,重啟XCode歧杏,然后編譯镰惦,就會顯示出編譯時間。
二 .代碼層面的優(yōu)化
? ? 1.forward declaration?所謂forward declaration犬绒,就是@class CLASSNAME旺入,而不是#import CLASSNAME.h。這樣凯力,編譯器能大大提高#import的替換速度茵瘾。
????2.?對常用的工具類進行打包(Framework/.a). 打包成Framework或者靜態(tài)庫急膀,這樣編譯的時候這部分代碼就不需要重新編譯了。? ??
? ? 3.常用頭文件放到預(yù)編譯文件里.? XCode的pch文件是預(yù)編譯文件龄捡,這里的內(nèi)容在執(zhí)行XCode build之前就已經(jīng)被預(yù)編譯卓嫂,并且引入到每一個.m文件里了。
? ?4.Debug模式下聘殖,不生成dsym文件.dysm文件里存儲了調(diào)試信息晨雳,在Debug模式下,我們可以借助XCode和LLDB進行調(diào)試奸腺。所以餐禁,不需要生成額外的dsym文件來降低編譯速度。
? ?5.Debug開啟Build Active Architecture Only.在XCode -> Build Settings -> Build Active Architecture Only 改為YES突照。這樣做帮非,可以只編譯當(dāng)前的版本,比如arm7/arm64等等讹蘑,記得只開啟Debug模式末盔。這個選項在高版本的XCode中自動開啟了。
? ?6.ebug模式下座慰,關(guān)閉編譯器優(yōu)化