IOS UIKIT_EXTERN, __attribute__((visibility ("default"))) 是啥玩意?


問題提出

在學習IOS時候,碰到一個函數NSStringFromCGPoint (UIGeometry.h)

其原型是 UIKIT_EXTERN NSString *NSStringFromCGPoint(CGPoint point);

 

 

原型分析

NSString* , CGPoint好理解, 前者是庫自帶的字符串類型, 后者是一個表示2維平面上的點的結構體。但是UIKIT_EXTERN是什么呢?
查找發現

UIKitDefines.h

1 #ifdef __cplusplus
2 #define UIKIT_EXTERN        extern "C" __attribute__((visibility ("default")))
3 #else
4 #define UIKIT_EXTERN            extern __attribute__((visibility ("default")))
5 #endif
6 
7 #define UIKIT_STATIC_INLINE    static inline

下面一行一行來看

line1: #ifdef __cplusplus, 說的是如果定義了 __cplusplus宏標識符, 則定義后面的內容(line2), 否則定義#else里面的內容(line4)

line2: #define UIKIT_EXTERN    extern "C" __attribute__((visibility ("default"))),

1. extern "C"是為了兼容以前的 C程序, 告訴編譯器按照以前C編譯方式對(全局)函數或變量進行編譯, 否則按照c++方式進行編譯[1]

eg. C方式編譯函數extern void fx(int , int), 不對函數名進行特殊處理編譯后函數名為_fx(.obj文件中)

但是C++方式編譯后, (為了支持重載)fx函數變成類似於_fx_int_int這樣的函數名, fx(int , float)會編譯成_fx_int_float (.obj文件)

2. __attribute__ 是設置函數屬性(或者變量屬性, 類型屬性), 可以設置的屬性包括

 1 packed,cleanup, common,nocommon,deprecated,mode,section,shared,tls_model,transparent_union[2]

visibility屬性是設置將本項目的函數作為庫使用時的可見性。g++編譯時, 加入-fvisibility=hidden參數, 會將所有默認public屬性設為hidden, 導致庫外文件不可見

3. 但是如果設置了__attribute__((visibility ("default")))的函數, 其public屬性仍能對外可見, 而不是hidden。可見編譯指令 -fvisibility是對所有屬性符號進行處理, 而__attribute__((visibility ("default")))是對特定函數可見性進行設置, 避免沖突[3]。

line3~6:忽略

line7:#define UIKIT_STATIC_INLINE    static inline, 靜態內聯

static 關鍵字修飾函數表示這是一個本地函數, 不能被沒有保護該文件(對該文件具有可見性的其他文件)引用、鏈接,編譯階段就能強制檢查

inline 關鍵字表示建議編譯器將該函數作為一個內聯函數,將函數內的代碼直接嵌入到每一個引用處,有點類似於宏定義直接替換,但是卻包含了編譯器嚴格的類型檢查,所以比宏定義安全,卻又有同樣的執行速度。

 

總結

UIKIT_EXTERN簡單來說,就是將函數修飾為兼容以往C編譯方式的、具有extern屬性(文件外可見性)、public修飾的方法或變量庫外仍可見的屬性

 

參考

 

[1] http://www.cnblogs.com/rollenholt/archive/2012/03/20/2409046.html
[2] http://blog.csdn.net/juana1/article/details/6849120
[3] http://blog.csdn.net/mrguanlingyu/article/details/23337885

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM