- const 简介(作用,与宏的区别)
一、
const 主要是用来修饰字符串常量的一个关键字。我们大部分的时候会把字符串常量抽成‘宏’来弄,但是苹果官方文档并不推荐我们这么做,苹果推荐我们使用const常量,苹果为什么推荐我们使用const来修饰字符串常量,这就要说下const 和 ‘宏’的区别了。
1、编译时刻:宏 是预编译(编译之前处理),const 是编译阶段,如果你过分的使用宏,那么程序每次启动前都需要把你写的宏 重新替换,容易造成编译时间久。
2、编译检查:宏不做检查,不会报编译的错误(我们用宏写的时候,即使写错了,系统也不会报错),const会做编译检查,如果有错误,会报编译错误。
3、定义区别:宏可以定义一些函数、方法,例如:
#define kScreenWidth CGRectGetWidth([UIScreen mainScreen].applicationFrame)
;但是const不可以。
注意:虽说使用宏会增加编译时间,但是并不会多消耗内存,宏定义的都是常量,常量都放在常量区,只会生成一份内存。如下图:
二、
我们要使用一个东西,首先要知道这个东西到底有什么用。
const的作用:限制类型
1、const 仅仅用来修饰右边的变量。
2、被const 修饰的变量是只读的。下面我们来看下const的基本使用
// 定义变量
int a = 1;
// 允许修改值
a = 20;
// const两种用法
// const:修饰基本变量
// 这两种写法是一样的,const只修饰右边的基本变量b
const int b = 20; // b:只读变量
int const b = 20; // b:只读变量
// 不允许修改值
b = 1;
// const:修饰指针变量*p,带*的变量,就是指针变量.
// 定义一个指向int类型的指针变量,指向a的地址
int *p = &a;
int c = 10;
p = &c;
// 允许修改p指向的地址,
// 允许修改p访问内存空间的值
*p = 20;
// const修饰指针变量访问的内存空间,修饰的是右边*p1,
// 两种方式一样
const int *p1; // *p1:常量 p1:变量
int const *p1; // *p1:常量 p1:变量
// const修饰指针变量p1
int * const p1; // *p1:变量 p1:常量
// 第一个const修饰*p1 第二个const修饰 p1
// 两种方式一样
const int * const p1; // *p1:常量 p1:常量
int const * const p1; // *p1:常量 p1:常量
三、
熟悉了const的作用,我们看下const在开发中的使用场景
1、当一个方法参数只读
2、定义只读全局变量
// 定义只读全局常量
NSString * const str = @"123";
// 当一个方法的参数,只读.
- (void)test:(NSString * const)name
{
//这里的参数 name是只读的,不可以更改。
}
- static 和 extern 简介(简单使用)
static 和 extern 和const一样,都是关键字,我们主要是要来看下他们的作用和如何简单的使用。
static作用
一、修饰局部变量
a、延迟局部变量的生命周期,程序结束才会销毁。
b、局部变量只会生成一份内存,只会初始化一次。
二、修饰全局变量
a、只能在本文件中访问,修改全局变量的作用域,生命周期不会改变。
// 全局变量:只有一份内存,所有文件共享,与extern联合使用。
int a = 20;
// static修饰全局变量
static int age = 20;
- (void)test
{
// static修饰局部变量
static int age = 0;
age++;
NSLog(@"%d",age);
}
上面代码中提到了,全局变量要和 extern 使用,可以全文件共享,下面我们来说下 extern(外部拓展)
extern作用
1、只是用来获取全局变量(包括全局静态变量)的值,不能用于定义变量。
extern原理
1、原理很简单,就是先在当前文件查找有没有全局变量,没有的话,去其它文件查找,然后使用。
如何使用extern?
.m
NSString * const nameKey = @"name";
.h(想在哪个文件里用,就用extern 来获取)
extern NSString * const nameKey = @"name";
说了这么多,最后我们说下 static / extern 和 const 的联合使用
- static / extern 和 const 的联合使用
一、static 和 const 联合使用
1、static 和 const作用:声明一个只读的静态变量
2、开发使用场景:在一个文件中经常使用的字符串常量,可以使用static 与 const组合
// 开发中常用static修饰全局变量,只改变作用域
// 为什么要改变全局变量作用域,防止重复声明全局变量。
// 开发中声明的全局变量,有些不希望外界改动,只允许读取。
// 比如一个基本数据类型不希望别人改动
// 声明一个静态的全局只读常量
static const int a = 20;
// staic和const联合的作用:声明一个静态的全局只读常量
// iOS中staic和const常用使用场景,是用来代替宏,把一个经常使用的字符串常量,定义成静态全局只读变量.
// 开发中经常拿到key修改值,因此用const修饰key,表示key只读,不允许修改。
static NSString * const key = @"name";
// 如果 const修饰 *key1,表示*key1只读,key1还是能改变。
static NSString const *key1 = @"name";
二、extern 和 const 联合使用
1、开发中使用场景:在多个文件中经常要使用同一个字符串常量,可以用extern 和 const 组合。
2、static与const组合:在每个文件都需要定义一份静态全局变量。
extern与const组合:只需要定义一份全局变量,多个文件共享 。
正常我们会写一个类,把我们所有用到的 常量 放到这里,然后定义全局变量,统一管理,方便开发。
GLConst.h
/*******************************文件标题****************************/
extern NSString * const Key = @"key";
/*******************************文件标题****************************/
GLConst.m
#import <Foundation/Foundation.h>
/*******************************文件标题****************************/
NSString * const Key = @"key";
/*******************************文件标题****************************/
我们要是想用这个全局变量 key 的话,我们只需要导入 GLConst 类的头文件,我们就可以使用了,正常情况下我们也不需要每个需要的类都导入 GLConst 的头文件,一般我们会放到 pch 文件里。ps:下一篇文章,我们会简单说下pch文件的创建与使用,和自定义的NSLog。(谢谢)