我建了一個iOS開發QQ交流羣:188647173,你們能夠一塊兒來相互學習。框架
還有一個羣裏面大神的我的站點www.mylonly.com,你們有不會的能夠向他請教。工具
Xcode會分步驟構建應用,這些步驟成爲構建階段,各個階段所作的事情以下,學習
(1)編譯源代碼(Compile Sources):該階段包含構建響應目標時須要編譯的源代碼。凡是加入項目中的源代碼,默認都會加入該構建階段。ui
(2)鏈接二進制文件和庫(Link Binary with Libraries):完成代碼的編譯後,Xcode會將其和框架(庫)鏈接,使代碼可以使用相應框架中的類。編碼
(3)拷貝程序包資源(Copy Bundle Resources):完成代碼的編譯和鏈接後,Xcode會生成一個可執行文件,並將其放入應用程序包(程序包實際上是一個目錄)。接着,Xcode會將拷貝程序包資源階段中的文件加入程序包。這些資源是運行應用時須要使用的數據文件,例如ViewController.xib、圖片和聲音文件。這些都是應用程序的組成部分。凡是加入項目的非源代碼文件,默認都會加入該構建階段。spa
一般會在編譯源代碼的時候發現錯誤,鏈接二進制文件和庫的階段有時也會出錯,若是瞭解各個階段的做用,就能夠更快地診斷和修正各個階段產生的錯誤。code
其實上述所說的三個過程,在Xcode中有所展現,可能咱們都不知道罷了,項目配置文件->Build Phrases,以下圖,接口
PS:「0依賴關係」這涉及到包依賴關係,我leader跟我說他最自豪的就是對於「包依賴關係」的掌控,這方面我還不是特別瞭解,還要多多學習。圖片
下面主要說下編譯階段和鏈接階段,資源
編譯階段--------預處理和編譯
編譯源代碼分爲兩個步驟:預處理和編譯。
預處理:預處理的做用是爲每一個實現文件(.m)建立一箇中間文件(intermediate file)。中間文件和實現文件同樣,都是Objective-C代碼,可是中間文件的體積可能會很大。
預處理器(preprocessor)處理完實現文件中的所有預處理指令後,會生成一箇中間文件。與處理指令四大有哎#的語句,例如#import、#define。。。,預處理器在處理#import語句時,會將該語句天換成導入文件的內容。例如ViewController.m文件中包含ViewController.h文件,ViewController.m生成的中間文件會包含ViewController.h和ViewController.m的所有代碼。不只如此,ViewController.h文件中還可能包含UIKit.h和CoreLocation.h,這兩個文件會導入更多的文件,導入的文件再導入其餘文件,以此類推,ViewController.m的中間文件是這些文件的代碼的集合。
可能有的童鞋沒有明白爲何預處理是在編譯代碼以前,我經過代碼來講明一下吧,咱們經過#define定義一個常量Debug,而後在#if~#elif~#endif中使用Debug常量,固然這裏的#if~#elif~#endif要在大括號{}中使用,例如將#if~#elif~#endif寫在-(viod)viewDidLoad{...}中,
#define Debug 0
#if Debug
NSLog(@"Debug is 0");
#elif
NSLog(@"Debug is not 0");
#endif
咱們在Xcode中看這段代碼的效果,以下圖,
你們看出上面圖片中NSLog顏色的不一樣嗎?此時Debug爲0,因此#if Debug後面的代碼不會在編譯的時候被編譯,#else後面的代碼會在編譯的時候被編譯,上面的代碼也說明在預處理階段,就肯定了哪些代碼會被編譯。因此說預編譯階段就是在編譯以前。
編譯:預處理完成後,Xcode會編譯以前生成的中間文件。Objective-C代碼會被轉換成機器碼,保存在目標文件中(object file)。一個目標文件對應一箇中間文件。在應用開發階段,大部分錯誤會發生在這個將代碼轉換成機器碼的編譯階段,編譯器「看不懂」代碼時會報錯,這些在編譯階段產生的錯誤成爲編譯時錯誤(compile-time errors)或語法錯誤(syntax errors)。
常見的編譯錯誤有放錯分號的位置、方括號([])或花括號({})不匹配、拼寫錯誤或字母大小寫錯誤等。使用未聲明的類也會致使此類錯誤發生,例如註釋掉#import "CoreLocation.h",這時候ViewController.m的中間文件包括來自CoreLocation.h的代碼,其中包括CLLOcationManager的接口聲明和CLLocationManagerDelegate的協議聲明,沒有相應的導入語句,這些文件就不會成爲所生成的中間文件的一部分,編譯器也就沒法處理相關的代碼。
鏈接階段:目標文件會包含(在實現文件中實現的)方法的機器碼。可是某個實現文件可能hi用到其餘實現文件的代碼,例如Appdelegate.m會使用到startUpdatingLocation方法,該方法的機器碼保存在CLLocationManger.m的目標文件中。編譯器不會將startUpdatingLocation方法的代碼拷貝至Appdelegate.m的目標文件中,而是設置一個鏈接,指向CLLocationManager.m的目標文件。鏈接二進制文件和庫就是處理這類鏈接的階段,該階段簡稱爲鏈接階段。
例如將Core Location框架和目標鏈接起來。框架是一組類的集合,類由兩個文件定義:頭文件和實現文件。框架的實現文件是已經預編譯好的,而且框架回家創立後的目標文件分紅一個或多個庫文件(因此Objective-C的框架沒有實現文件,相應地文件已轉成機器碼)。凡是用到Core Location框架代碼的類,編譯器都會在其目標文件中放置相應地鏈接,指向Core Location庫。
若是編譯器沒法處理某個鏈接(例如沒法找到包含相應代碼的目標文件,或是目標文件沒有包含被引用的代碼),就會產生鏈接錯誤。例如在使用Core Location中的類時候沒有引入CoreLocation.framework框架,就會出現鏈接錯誤的紅色警告。
我的總結:這些編譯過程方面的知識點很容易理解,可是每每被咱們所忽視。因此在編碼之餘,拿出工具書看看理論講解,確定可以提升本身對於編碼的理解。