iOS基础之define,const,extern,static

来源:互联网 发布:标的物 知乎 编辑:程序博客网 时间:2024/05/16 07:11

16th,August,2016

define VS const

宏(define)跟常量(const)的区别:

宏是做预编译处理,但不会检查,只是做简单的替换操作。大量的宏需做大量的替换工作导致编译时间久,且没有类型安全检查,在替换过程中可能会产生意想不到的错误。且宏在一些情况下会消耗比较多的内存。因而,苹果不推荐使用宏,推荐使用const。
const会编译检查,也会报编译错误,即做类型安全检查工作。但宏能定义一些const无法定义的方法。

NSString *const str = @"123";

ps:预编译,又称预处理,做些代码文本替换的工作,属于整个编译过程最先做的工作。常见的预编译指令,#include,#define,#if #else #endif。

extern VS static

extern

声明全局只读变量, 原理-> 现在当前文件查找全局变量,无则去其他文件查找。不具备隐藏性,也就是避免重复包含和命名问题。无需引入头文件

extern NSString *str = @"123";// 这样声明会出现警告"extern variable has an initializer",?:应该是因为extern代表声明而不是定义,但编译器只是警告而不是报错int foo(int arg1, char arg2);// 声明函数时,编译时编译器会自动添加extern,变量则不会自动添加。因为如果是函数,仅仅表示声明,此时并未给函数分配存储空间,编译时默认添加extern。如果声明的是变量(其实准确的说是定义变量),则表示变量被声明和定义了,因而不想函数一样添加extern。

static

声明静态局部变量。
1. 这里的局部算是广义的,包括函数内或本文件内两种情况,即使在同一文件内定义了同名的函数内静态变量与文件内全局静态变量,两者也是相互独立的,也就是两个是不同的变量。在声明函数内静态变量的函数以外访问该变量,则是访问文件内全局静态变量。相比于全局变量, 具有隐藏性,也就是不同文件定义同名函数和变量不会冲突。
2. 存放在静态数据区。具备持久性和默认值为0。只会生成一份内存,生命周期直至程序结束才会销毁。(ps: 全局变量也是存放在静态数据区,默认值也是为0)

static NSString *str = @"123";

extern const VS static const

常量即在程序运行过程中值不会被修改

static const

单个文件内。
开发使用场景:在一个文件内经常使用到的字符串常量

// static 与 const 组合使用static NSString * const kUser = @"com.jy.user";

extern const

工程内全局共享,建议整理到一个文件中GlobalConst,将工程中的所有全局变量统一管理。
开发使用场景:多个文件内都会使用到的字符串常量。

// .h文件中extern NSString * const kUser;// .m文件中NSString * const kUser = @"com.jy.user"

15th,August,2016

FOUNDATION_EXPORT VS extern

在读AFNetworking->AFNetworkingReachabilityManager代码中
.h文件为:

FOUNDATION_EXPORT NSString * const AFNetworkingReachabilityDidChangeNotification;

.m文件为:

NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change";   

那么extern跟FOUNDATION_EXPORT有什么区别呢


17th,August,2016
先看看NSObjCRuntime.h对FOUNDATION_EXPORT 的定义

// NSObjCRuntime.h中#if defined(__cplusplus)#define FOUNDATION_EXTERN extern "C"#else#define FOUNDATION_EXTERN extern#endif#if TARGET_OS_WIN32    #if defined(NSBUILDINGFOUNDATION)        #define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllexport)    #else        #define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllimport)    #endif    #define FOUNDATION_IMPORT FOUNDATION_EXTERN __declspec(dllimport)#else    #define FOUNDATION_EXPORT  FOUNDATION_EXTERN    #define FOUNDATION_IMPORT FOUNDATION_EXTERN#endif

也就是C++编译成extern “C”,其它情况编译成extern。以及在OS_WIN32下的一些处理。大体上大多数项目中跟extern是没什么区别,总的说FOUNDATION_EXPORT兼容性更好吧。如果项目中有使用C或C++的库,FOUNDATION_EXPORT能和C或C++库更好的兼容。
建议 使用FOUNDATION_EXPORT。


小结

  1. const声明的变量是只读的,static声明的变量改变后会保存改变,extern则声明全局变量。
  2. extern仅表示声明变量和函数,未分配内存或空间。
  3. 大量的宏定义会影响编译速度。推荐使用const而非define

创建单例的时候为什么使用static

不使用static,可能被释放,就无法实现共享数据。防止随便创建新的实例

参考资料

When to use FOUNDATION_EXPORT?

0 0
原创粉丝点击