码农的世界将来跳槽用

const static extern关键字作用和对比

2018-08-08  本文已影响2人  NotFunGuy

const

const修饰的为常量,在程序中,常量的值是固定的不能改变的。const有以下两个作用:

比如声明一个值为1的常量a,然后尝试对这个常量a的值做修改:

// a 是一个常量
int const a = 1;

下面代码会报错:Cannot assign to variable 'a' with const-qualified type 'const int'

a = 20;

需要注意的是const能修饰基本变量和指针变量。需要注意他们的区别

int const p; // 是基本变量 const修饰之后 p变为readonly
int const *p; // *p为指针遍历, const修饰之后, *p变为readonly
int *const p; // p为基本变量 const修饰之后 p变为readonly

const的使用

定义一个全局常量,比如有时候使用宏定义
#define

#define APPKEY = @"appeky";

也可以使用const定义一个全局常量

NSString *const appKey = @"appeky";

static

static修饰局部变量

使用static修饰局部变量能够保证局部变量只初始化一次,也就是程序在运行过程中永远只有一份内存,相当于生命周期是整个程序的生命周期。通常在单例中比较常见

+(Person *)sharedManager {
    static dispatch_once_t onceToken; // static修饰局部变量, 保证只初始化一次
    dispatch_once(&onceToken, ^{
        _sharedManager = [[self alloc] init];
    });
    return _sharedManager;
}

接下来看一下使用static修饰的局部变量和不使用static修饰的局不变的区别:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    int idx = 0;
    NSLog(@"idx = %d", idx++);
}

每次点击屏幕之后,打印出的idx都是0,那是当第一次进来touchesBegan:withEvent:,先声明一个int型的值为0的idx局部变量,当方法运行完之后这个局部变量的生命周期也就结束了。下一次进来这个方法的时候就重新初始化。

2018-08-08 11:02:05.441311+0800 iOSTest[14608:2029602] idx = 0
2018-08-08 11:02:05.836638+0800 iOSTest[14608:2029602] idx = 0
2018-08-08 11:02:06.859228+0800 iOSTest[14608:2029602] idx = 0
2018-08-08 11:02:07.243072+0800 iOSTest[14608:2029602] idx = 0
2018-08-08 11:02:07.444190+0800 iOSTest[14608:2029602] idx = 0
2018-08-08 11:02:07.601846+0800 iOSTest[14608:2029602] idx = 0

现在给idx加上static修饰,运行之后会有如下打印结果,那是因为static修饰之后idx变成了一个静态的局部变量,即是touch方法走完了,它的生命周期仍然没有结束。下次进来的时候就不需要重新初始化,保证了只初始化一次。

static int idx = 0;
2018-08-08 11:03:31.436579+0800 iOSTest[14632:2034568] idx = 0
2018-08-08 11:03:32.147773+0800 iOSTest[14632:2034568] idx = 1
2018-08-08 11:03:32.563940+0800 iOSTest[14632:2034568] idx = 2
2018-08-08 11:03:32.845052+0800 iOSTest[14632:2034568] idx = 3
2018-08-08 11:03:33.216545+0800 iOSTest[14632:2034568] idx = 4

static修饰全局变量

使用static修饰全局变量能够使全局变量的作用域仅限于当前文件内部,即当前文件内部才能访问该全局变量。
首先肯定有疑惑,某个文件的全局变量,在另外一个文件中能够访问么?
关于这个问题,我们在两个不同的文件中写两个相同的全局变量:
在新建的继承自NSObject的Person.m文件中:

#import "Person.h"

NSUInteger age;  // 全局变量

@implementation Person
@end

让后在ViewController中同样声明age全局变量,尝试是否能访问到Person中的age,发现并不能。


image

删去这句代码之后运行,发现报错


image

综上结果:实际上在一个文件中的全局变量在工程的其他文件也是能访问的。如果想要限定只在当前文件访问,可以使用static修饰。

static NSUInteger age;

通常,也是在以GCD创建的单利中使用的比较多

@implementation Person

// static修饰全局变量,让外界文件无法访问
static Person *_sharedManager = nil;

+(Person *)sharedManager {
    static dispatch_once_t onceToken; // static修饰局部变量, 保证只初始化一次
    dispatch_once(&onceToken, ^{
        _sharedManager = [[self alloc] init];
    });
    return _sharedManager;
}

@end

static修饰函数

这个在ios中用的比较少,多见与C++中。

extern

extern的作用是声明外部全局变量,这个和static正好相反。
比如在一个工程中,很多文件可能都需要使用同一个变量,比如网络请求的基地址等,就可以放在一个单独的文件中,使用欧冠extern关键字声明为外部全局变量。
需要注意的是extern只能声明,不能用于实现
.h

extern NSString *const baseUrl;

.m

NSString *const baseUrl = @"https://www.xxx/";
上一篇 下一篇

猜你喜欢

热点阅读