ios 中內聯函數例子有:
@property(nonatomic)UIEdgeInsetsscrollIndicatorInsets;
typedefstructUIEdgeInsets{CGFloattop, left, bottom, right;// specify amount to inset (positive) for each of the edges. values can be negative to 'outset'}UIEdgeInsets;
UIKIT_STATIC_INLINE UIEdgeInsets UIEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right) {
UIEdgeInsets insets = {top, left, bottom, right};returninsets;
}
內聯函數 是為了解決函數調用效率的問題
由于函數之間的調用,會從一個內存地址調用到另外一個內存地址,當函數調用完畢之后還會返回原來函數執行的地址,函數調用會有一定的時間開銷,引入內聯函數是為了解決這一問題
沒有使用 內聯函數 static inLine 的main.m 匯編代碼:
使用內聯函數 static inLine 源代碼:
使用內聯函數 static inLine 的 main.m 匯編代碼:
對比兩者的mian.m的匯編代碼,可以發現,沒有使用`static inline修飾的內聯函數的mian函數匯編代碼中,會出現 call 指令!這就是區別!調用call指令就是就需要:
-(1)將下一條指令的所在地址(即當時程序計數器PC的內容)入棧
-(2)并將子程序的起始地址送入PC(于是CPU的下一條指令就會轉去執行子程序)。
查看匯編代碼的方法:選中main.m文件-->Xcode 菜單 --> Product --> Perform Action --> Assemble "main.m"
結論
1.使用 inline 修飾的函數,在編譯的時候,會把代碼直接嵌入調用代碼中.就相當于用 #define 宏定義來定義一個 add 函數那樣 與 #define 的區別是:
1) ?#define 定義的格式要有要求,而使用 inline 則就就像平常寫函數那樣,只要加上 inline 即可
2) ?使用 #define 宏定義的代碼 ,編譯器不會對其進行參數有效性檢查,僅僅只是對符號表進行替換.
3) ?#define 宏定義的代碼,其返回值不能被強制轉換的適合的轉換類型.
2.在 inline 加上 "static" 修飾符,只是為了聲明該函數只在該文件中可見! 也就是說,在同一個工程中,就算在其他文件中出現同名,同參數也不會引起函數重復定義的錯誤
inline 與 宏的區別
優點相比于函數:
1) inline函數避免了普通函數的,在匯編時必須調用call的缺點:取消了函數的參數壓棧,減少了調用的開銷,提高效率.所以執行速度確比一般函數的執行速度要快.
2)集成了宏的優點,使用時直接用代碼替換(像宏一樣);
優點相比于宏:
1)避免了宏的缺點:需要預編譯.因為inline內聯函數也是函數,不需要預編譯.
2)編譯器在調用一個內聯函數時,會首先檢查它的參數的類型,保證調用正確。然后進行一系列的相關檢查,就像對待任何一個真正的函數一樣。這樣就消除了它的隱患和局限性。
3)可以使用所在類的保護成員及私有成員。
inline內聯函數的注意事項
1.內聯函數只是我們向編譯器提供的申請,編譯器不一定采取inline形式調用函數.
2.內聯函數不能承載大量的代碼.如果內聯函數的函數體過大,編譯器會自動放棄內聯.
3.內聯函數內不允許使用循環語句或開關語句.
4.內聯函數的定義須在調用之前.