基本知识:
- 函数或变量在声明时,并没有给它实际的物理内存空间,它有时候可以保证你的程序编译通过, 但是当函数或变量定义的时候,它就在内存中有了实际的物理空间。
- 如果你在编译模块中引用的外部变量没有在整个工程中任何一个地方定义的话, 那么即使它在编译时可以通过,在连接时也会报错,因为程序在内存中找不到这个变量!
- 对于一个完整的程序,内存中的分布情况:
| 代码区 |
| 全局数据区 |
| 堆区 |
| 栈区 |
1. extern
extern用于变量的声明,告诉编译器:已经存在一个全局变量,但是不在当前的编译单元内,需要连接的时候在其他编译单元中寻找。
2. static
2.1. 修饰全局变量、函数 -
修改变量作用域为当前编译单元,变量生命周期不变;
避免重复定义全局变量
2.2. 修饰局部变量 -
修改变量的生命周期为整个工程周期,变量作用域不变
3. const
const修饰右边的变量,用来限制变量为只读属性。
3.1. 对于基本类型
const int r=100; // 声明加初始化,r为常量100
3.2. 对于指针
int n = 10;
1. const int *p = &x; // const修饰指针,即指向的内存空间不能通过指针进行改变。但是可以改变p,即可以指向其他变量
2. int const *p = &x; // 与1完全相同
3. int *const p = &x; // const修饰p,p的内容不能变,即p指向的内存空间不能变。但是该内存空间存储的值是可以通过指针进行改变的
4. const int *const p = &x; // p内容和指向内容均不可以改变
4. define
在程序的预编译阶段进行替换处理。
5. define与const
区别:
- define宏是在预处理阶段展开。
const常量是编译运行阶段使用。 - define不做检查,不会报编译错误,只是替换
const会编译检查,会报编译错误 - define在展开的时候才分配内存,展开几次分配几次内存
const在定义的时候会分配一次内存到静态区,使用时不重复分配 - define可以定义一些简单的运算函数
使用场景:
- 定义一个字符串常量:
#define NAME @"henry"
static NSString *const name = @"henry";
两个均可使用,因为OC中的字符串常量存储在静态区,即相同的字符串常量在内存中只会存储一份。
但是苹果的代码中较多使用的是const
- 使用define定义简单的函数
// rgb颜色转换(16进制->10进制)
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
6. static和const的联合使用
声明一个只读的静态变量
使用场景:
在一个文件中经常使用的常量,可以使用static与const组合
static const CGFloat cellHeight = 80;
static NSString *const baseURL = @"60.123.123.123:2016"
7. extern和const的联合使用
在多个文件中经常使用的同一个全局变量。
使用场景:
- 开发中为了管理所有的全局变量,通常搞一个GlobeConst文件,里面专门定义全局变量,统一管理,要不然项目文件多不好找。
GlobeConst.h 文件中
extern NSString * const kBaseURL;
=====================
GlobeConst.m文件中
NSString * const kBaseURL = @"60.123.123.123:2016"
一般iOS的SDK的头文件中常采用这种方式,如:
extern NSString *const UIWindowDidBecomeKeyNotification;
百度云推送头文件