static, const, exter
static
用途
-
static主要使用在想要延长一个变量的生命周期或者更改作用域的时候,主要作用如下
- 局部变量:延长生命周期,作用域不变
- 全局变量:缩小作用域
为了区分这两点,下面我再详细介绍
修饰局部变量时
如果直接在局部声明一个变量,每次进入这个局部(比如一个函数),就会重新分配内存,重新初始化,函数执行完就被销毁
通过前面C语言的学习,我们知道要想在一个函数内反复访问函数里的变量,并且让这个值能记住上一次的结果,最简单的方式就是把这个变量定义在外面,这样做的逻辑是将原本作用域在函数内部的变量调整为作用域为包括函数外,所以函数访问的时候能对上一次的值进行操作
- 但还有另一个方法,那就是加上static关键字,加上这个关键字之后,该变量只会在第一次读到它的时候创建出来,后面再访问的时候,都会取出它原来的值进行操作,这样做的好处就是,不会扩大变量的作用域,只是让变量活得更久
请看以下代码
objc
- (void) btnTapped:(UIButton *)btn {
static int count = 0;
count++;
NSLog(@"点击了%d次按钮", count);
}
- 如果去掉static,无论点击多少次,显示的都是1,这是因为每次被销毁初始化,count的值都会回到1,为了统计总共的次数,所以我们就加上了static修饰
另外一提,这种模式类似于单例,第一次读到的时候会进行初始化,后面每次读到都会取出前面的值
修饰全局变量时
我们知道,全局变量在整个文件中都是可见的,比如我们在A.m中声明一个全局变量,在B.m中可以通过extern关键字取出来使用(具体后面进行讲解),但是如果我们不想这样,只是想要在当前文件访问的时候,就可以在变量前面加上static修饰
objc
// FileA.m
NSString *name = @"dyyxs";
// FileB.m
extern NSString *name;
- (void)test {
NSLog(@"%@", name);
}
如果在A的前面加上static,b将访问不到这个变量
extern
用途
用于多个文件共享全局变量或者函数的时候,它本身不分配内存,不定义,只是告诉编译器这个东西在其他地方定义了,你自己去找
声明全局变量
普通的用法我在上面演示过,那就是在一个文件中想取另一个文件的变量,直接使用extern让编译器去找,还有一个更方便的用法,如下
objc
//A.h
extern NSString *userName;
//A.m
NSString *userName = @"dyyxs2007";
- 这样做的好处就是,其他文件引入A.h的时候就能直接用那个变量,不需要反复extern
声明函数
看完上面对变量声明的简化版,我们细想另外一个问题:对一个函数而言,我们正常是在.h里面声明,在.m里面使用,这样和那个简化版其实有着同样的结构
objc
// 隐藏extern
CGFloat Dyyxs(void);
// 不隐藏extern
extern CGFloat Dyyxs(void);
以上两个写法等价
从这之中我们就能分析出,一个函数默认就是extern(全局可调用)的,所以如果想要一个函数只在当前.m文件中可用的时候,就需要用static修饰
const
const用来修饰一个值,表示它只读,存储在常量区,关心的是这个变量能不能改,接下来我们分析一个常见且重要的问题
const写在*的前面还是后面
- const NSString *name 指针指向的内容只读
- NSString *const name 指针本身只读
- const NSString *const name 都只读