pch讓編譯更快
在日常的開發(fā)中舰始,有很多地方會(huì)用到Foundation和UIKit,使用之前需要先將頭文件#import進(jìn)來咽袜。與C語言中的#include相似丸卷,import會(huì)把頭文件里的代碼copy過來,只不過#import可以避免重復(fù)引用询刹。比如谜嫉,#import "Test.h"
等同于:
#ifndef Test_h
#define Test_h
#include "Test.h"
#endif
如果你的應(yīng)用依賴于UIKit萎坷,那么每次編譯應(yīng)用都需要去編譯UIKit,這會(huì)增加build的時(shí)間沐兰。<b>節(jié)約生命哆档,從減少build時(shí)間開始。</b>
預(yù)編譯頭文件住闯,顧名思義瓜浸,是將頭文件事先編譯成一種二進(jìn)制的中間格式。在整個(gè)編譯過程中比原,只編譯一次插佛,并且會(huì)有緩存,如預(yù)編譯頭所涉及的部分不發(fā)生改變的話量窘,在隨后的編譯過程中此部分不會(huì)重新進(jìn)行編譯雇寇,從而大大提高編譯速度。
在iOS開發(fā)中绑改,我們可以在xxx.pch中定義需要預(yù)編譯的頭文件谢床,在Xcode 6 之前,自動(dòng)生成的pch如下:
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#endif
pch的副作用
加入pch中的頭文件厘线,在項(xiàng)目其他地方要使用時(shí)识腿,就不需要再import了造壮。這可以算是一種便利,但它也是副作用的源頭耳璧。切記:<b>pch的目的是提高編譯速度,而不是讓你少打幾行import代碼旨枯。</b>
- 不利于代碼移植
如果同一份代碼需要在多個(gè)項(xiàng)目中使用蹬昌,過度使用pch會(huì)帶來麻煩。假設(shè)項(xiàng)目A的pch中加了這樣一行代碼:#import <Security/Security.h>
攀隔,而你的某個(gè)組件使用了Security皂贩,將組件代碼copy到項(xiàng)目B去可能編譯不了昆汹,因?yàn)轫?xiàng)目B的pch并沒有添加Security.h - 隱式依賴關(guān)系
本來我們可以通過掃描xxx.h和xxx.m文件明刷,找到xxx所依賴的模塊满粗。但是濫用pch會(huì)讓這些依賴關(guān)系被掩蓋辈末,因?yàn)槟愕奈募赡茈[式地依賴了pch中定義的某些頭文件。我在另外一篇文章架構(gòu)設(shè)計(jì)中的循環(huán)引用中提到文件之間不應(yīng)該循環(huán)引用,否則系統(tǒng)將越來越復(fù)雜和不可維護(hù)挤聘。
有節(jié)制地使用pch
在Xcode 6之后轰枝,新建項(xiàng)目已經(jīng)不會(huì)自動(dòng)生成pch文件了组去。
個(gè)人認(rèn)為原因有兩個(gè):
- 因?yàn)樗母弊饔?/li>
- Modules的引入可以更好地替代預(yù)編譯頭
iOS 7之后,系統(tǒng)的Module都可以被"semantic import"添怔。使用起來很簡(jiǎn)單贤旷,把原來的#import換成@import即可。比如:#import <Foundation/Foundation.h>
換成@import Foundation;
即可艾杏。
編譯器遇到@import
時(shí),會(huì)將預(yù)編譯好的framework載入购桑,同時(shí)也不需要到project settings里添加framework氏淑,系統(tǒng)會(huì)幫你做這些事情。<b>所有重復(fù)性的勞動(dòng)都應(yīng)該被自動(dòng)化假残。</b>這些Module只會(huì)編譯一次,因此已經(jīng)可以不用pch了辉懒。
不過,pch也并沒有完全退出歷史舞臺(tái)莹汤。有一些場(chǎng)景還是會(huì)使用到颠印,比如你的每個(gè)文件都需要用到你定義的一些方法。加入pch的文件應(yīng)該滿足:
- 幾乎所有文件都會(huì)用到嗽仪。
- 不應(yīng)該經(jīng)常改動(dòng)。宏定義沽翔,常量定義等不應(yīng)該放在pch里,pch應(yīng)該只有
#import
或者#include
。
有節(jié)制地用仅偎,寧可多敲幾行代碼,不要偷懶把很多東西都放pch里橘沥。