废话不多说,直接上!!!
const
const常量与宏的区别,很多同学喜欢宏来定义常量,其实这里是不推荐的(苹果也不推荐,有兴趣的同学可以研究一下,苹果的库里常量一般都是用const定义的,例如:key的定义,delegate的name等)
const与宏的比较:
- 宏是预编译,const是编译阶段,大量使用宏定义会是编译时间变长
- 宏只做简单替换,不会检查报错,const在编译阶段会检查报错
- 宏可以定义函数、方法,使代码简洁,const不能
因此建议定义函数、方法等时使用宏,而定义常量时尽量使用const
const修饰指针类型和基本数据类型
const修饰基本数据类型
// 以下两种写法是一样的
int const a = 5;
const int b = 5;
// 被const修饰的变量变成常量,不可修改,下面这种写法会 报错
a = 10;
b = 10;
const修饰指针类型
int b = 10;
int a = 5;
// const修饰的是指针变量p,p(即地址)不可变,*p(地址指向的值)可变
int * const p1 = &a;
p1 = &b; // 报错
*p1 = 10; // 不会报错
// const修饰的是变量*p,p(即地址)可变,*p(地址指向的值)不可变
const int *p2 = &a;
p2 = &b; // 不会报错
*p2 = 10; // 报错
// const修饰的是变量*p,p(即地址)不可变,*p(地址指向的值)不可变
const int * const p3 = &a;
p3 = &b; // 报错
*p3 = 10; // 报错
开发中使用场景
- (void)viewDidLoad {
[super viewDidLoad];
int a = 10;
[self test1:&a];
NSLog(@"%d", a); // a = 0;
[self test2:&a];
NSLog(@"%d", a); // a = 0;
}
/// 需求:调用此方法,将计算结果通过参数传回
- (void)test1:(int * const)a {
// 根据需求,我们需要限制 只能修改指针指向的值 不可修改参数指针地址
int b = 0;
*a = b;
// a = &b; // 会报错,不可修改指针指向,只能通过指针
}
/// 需求:此方法内只能读取参数的值,不可修改
- (void)test2:(const int *)a {
// *a = 0; // 会报错,不可修改值,只能读取
int b = 5;
a = &b; // 可以修改指针地址
}
static
static修饰局部变量和全局变量效果不同
static修饰局部变量
- 延长局部变量的生命周期, 到程序结束才会销毁。
- 使局部变量只会生成一份内存,只会初始化一次。
- (void)test {
static NSInteger a = 0;
a += 1;
NSLog(@"a = %ld", a);
}
[self test]; // a = 1;
[self test]; // a = 2;
[self test]; // a = 3;
常见使用场景:创建单利对象
static修饰全局变量
先说一下全局变量:
生命周期
:全局变量默认生命周期是直到序结束才会销毁
作用域
:作用域在程序所有文件
弊端
:造成重复定义,通常会和extern配合使用,下面讲extern再说
- static修饰全局变量会改变作用域,只能在当前文件中访问,外部无法访问,即使使用extern声明也不行(会报错)
extern
// extern通常都会配合const一起使用,
extern NSString * const text;
extern只是用来获取全局变量(包括全局静态变量)的值,不能用于定义变量
extern会先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找
const、static、extern三者配合使用
static和const配合使用
通常我们需要在一个文件内定义一个全局常量,只能在当前文件内使用,可以使用static和const配合使用
// 定义一个test在当前文件全局使用
// static: 使test只在当前文件内有效,外界无法访问,extern声明也不行
// const: 使test不可修改,保证值不变
// 弊端:假如test在其他文件内也需要使用,那么就需要在其他文件内也这样定义一个全局常量,浪费资源
static NSString * const test = @"test";
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
@end
const和extern配合使用
通常我们在一个文件内定义了一个全局的常量,假如在其他文件内也需要访问此常量,只需要使用extern声明即可使用,无需重复定义
// 定义一个test全局常量
// const: 使test不可修改,保证值不变
NSString * const test = @"test";
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
@end
////////////////////////////////////////
// 现在我们在其他文件中也需要使用test
// NSString * const test = @"test"; // 会报错, 重复定义了
extern NSString * const test; // 使用extern声明test,不能再初始化
@implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"test = %@", test); // test = test
}
@end
总结
- static与const组合:在每个文件都需要定义一份静态全局变量,仅供当前文件使用
- extern与const全局变量组合:只需要定义一份全局变量,多个文件共享。
PS:在实际开发中,通常会把所有的全局变量放到一个文件内,便于管理
GlobeConst.h
extern NSString * const nameKey;
extern NSString * const titleKey;
...
GlobeConst.m
NSString * const nameKey = @"nameKey";
NSString * const titleKey = @"titleKey";
...
。
。
。
感谢您看完了,以上纯属个人理解,希望对您有所帮助!