inline
在iOS中的一些框架中,static inline是經(jīng)常出現(xiàn)的關(guān)鍵字組合.
- static自不用多說,表示在當前文件中應(yīng)用,如 static A, 在其它文件中也可以出現(xiàn)static A.不會導(dǎo)致重名的錯誤.
- inline.內(nèi)聯(lián)函數(shù).
- 作用:替代宏.
(如果你在看框架時,看到inline不解,搜索到這篇文章,看到這里可以不用看下面的詳述了)
- 在框架中出現(xiàn)inline時,如YYKit框架.我們稍加觀察就會發(fā)現(xiàn)它出現(xiàn)在.h文件中. such as:
static inline CGFloat CGFloatFromPixel(CGFloat value) {
return value / YYScreenScale();
}
//YYScreenScale()方法說明:
CGFloat YYScreenScale() {
static CGFloat scale;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
scale = [UIScreen mainScreen].scale;
});
return scale;
}
雖然static inline修飾的是函數(shù)(或者方法,swift出來后,我覺著方法==函數(shù),朋友們不用咬文嚼字,鄙視我輩了).但它在這里就是宏的作用,即你可以將CGFloatFromPixel當作一個宏.
當然inline函數(shù)與宏有區(qū)別,inline可以:
- 解決函數(shù)調(diào)用效率的問題:
- 函數(shù)之間調(diào)用,是內(nèi)存地址之間的調(diào)用活翩,當函數(shù)調(diào)用完畢之后還會返回原來函數(shù)執(zhí)行的地址啊胶。函數(shù)調(diào)用有時間開銷,內(nèi)聯(lián)函數(shù)就是為了解決這一問題奇钞。
- 不用inline修飾的函數(shù), 匯編時會出現(xiàn) call 指令.調(diào)用call指令就是就需要:
- (1)將下一條指令的所在地址入棧
- (2)并將子程序的起始地址送入PC(于是CPU的下一條指令就會轉(zhuǎn)去執(zhí)行子程序).
結(jié)論
為什么inline能取代宏?
優(yōu)點相比于函數(shù):
- inline函數(shù)避免了普通函數(shù)的,在匯編時必須調(diào)用call的缺點:取消了函數(shù)的參數(shù)壓棧,減少了調(diào)用的開銷,提高效率.所以執(zhí)行速度確比一般函數(shù)的執(zhí)行速度要快.
2)集成了宏的優(yōu)點,使用時直接用代碼替換(像宏一樣);
優(yōu)點相比于宏:
1)避免了宏的缺點:需要預(yù)編譯.因為inline內(nèi)聯(lián)函數(shù)也是函數(shù),不需要預(yù)編譯.
2)編譯器在調(diào)用一個內(nèi)聯(lián)函數(shù)時涯雅,會首先檢查它的參數(shù)的類型,保證調(diào)用正確展运。然后進行一系列的相關(guān)檢查活逆,就像對待任何一個真正的函數(shù)一樣。這樣就消除了它的隱患和局限性拗胜。
3)可以使用所在類的保護成員及私有成員蔗候。
inline內(nèi)聯(lián)函數(shù)的說明
- 1.內(nèi)聯(lián)函數(shù)只是我們向編譯器提供的申請,編譯器不一定采取inline形式調(diào)用函數(shù).
- 2.內(nèi)聯(lián)函數(shù)不能承載大量的代碼.如果內(nèi)聯(lián)函數(shù)的函數(shù)體過大,編譯器會自動放棄內(nèi)聯(lián).
- 3.內(nèi)聯(lián)函數(shù)內(nèi)不允許使用循環(huán)語句或開關(guān)語句.
- 4.內(nèi)聯(lián)函數(shù)的定義須在調(diào)用之前.
參考資料:
http://stackoverflow.com/questions/11985307/static-extern-and-inline-in-objective-c