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
时间: 2024-08-11 04:57:27

IOS UIKIT_EXTERN, __attribute__((visibility ("default"))) 是啥?的相关文章

__attribute__((visibility("default"))) [转]

-fvisibility=default|internal|hidden|protected gcc的visibility是说,如果编译的时候用了这个属性,那么动态库的符号都是hidden的,除非强制声明. 1.创建一个c源文件,内容简单 #include<stdio.h> #include<stdlib.h> __attribute ((visibility("default"))) void not_hidden () { printf("expo

ios项目icon和default图片命名规则

一.应用图片标准iOS控件里的图片资源,苹果已经做了相应的升级,我们需要操心的是应用自己的图片资源.就像当初为了支持iPhone 4而制作的@2x高分辨率版本(译者:以下简称高分)图片一样,我们要为iPad应用中的图片制作对应的高分版本.我知道不少开发者很有预见性的早在iOS 5.0 SDK上就完成了这一步升级.可是我还是要强调一点,那就是之前 Michael Jurewitz (@Jury)在推上提到过的: — 如果想让你的高分图片显示在新iPad上,你必须用Xcode 4.3.1 连同iOS

__attribute__ ((default)) 和 __attribute__ ((hidden))

制作一个共享库 1 /* a.h */ 2 int func(); 1 /* a.c */ 2 #include <stdio.h> 3 #include "a.h" 4 5 int func() 6 { 7 printf("### func ###\n"); 8 return 0; 9 } gcc -shared -o liba.so a.c -fPIC main.c 1 #include "a.h" 2 3 int main()

iOS 从main函数开始

app程序的入口,同样是main函数 main函数为 int main(int argc, char * argv[]),C系语言大多都是这个样子,argc是命令行总的参数个数,argv是参数的数组,值得一提的是argv中第一个参数为app的路径+全名. 然后就是main中的代码 @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } autor

七:定义全局变量的方法以及UIKIT_EXTERN简单理解

一.定义全局变量: 创建类文件 在.h中: 1 #import <UIKit/UIKit.h> 2 3 UIKIT_EXTERN CGFloat const ZWTitlesViewH; 4 UIKIT_EXTERN CGFloat const ZWTitlesViewY; 在.m中: 1 #import <UIKit/UIKit.h> 2 CGFloat const ZWTitlesViewH = 35; 3 CGFloat const ZWTitlesViewY = 64; 再

基于Linux下的GCC编译器的内部预宏定义与__attribute__属性

***************************************************************************************************************************** 作者:EasyWave                                                                                    时间:2015.02.20 类别:Linux应用-GCC编

react native 0.50 源码解析 再出发 持续更新

1.核心类 1.1 RCTRootView 一个RCTRootView持有一个RCTBridge成员变量 RCTRootView : UIView RCTBridge *bridge; UIViewController *reactViewController; UIView *contentView; UIView *loadingView; 1.2 RCTBridge 一个RCTBridge持有一个RCTCxxBridge成员变量 RCTBridge.h @interface RCTBrid

C语言之预处理

1 #define name value 我再学习预处理直接的驱动力是看了php的源码,开头一大推的宏定义器,之前'掌握'的一点#define的用法太少了,根本看不懂源码中宏的处理逻辑和运行的路径.所以再学习预处理器很有必要,里面好多东西其实并不难,只是你没有接触到,等你学习了,就感觉容易了. 一.宏定义和使用中的坑 这小节采用先给代码再说明的形式,这样你可以看看每个代码的运行结果是否和你预期的一致! 宏是什么,宏就是#define机制把指定的参数替换的文本中,这样的实现方式就是宏.使用宏定义可

software with plugin

Linux 查看一个动态库的符号 nm -D plugin.so Windows dumpbin /exports plugin.dll linux 的符号是默认所有导出的,而windows是默认hide的. #define ALPHAAPI __attribute__ ((visibility("default"))) #define ALPHAAPI __attribute__ ((visibility("hidden")))