讲解前先说下三个词的意思
const 常量
static 静态
extern 查找引用
在项目中我们经常会用到宏定义,例如#define ANIMATION_DURATION 0.5
.嗯,这么写很方便,但是殊不知它也是有缺点的,比如说:宏定义仅仅是简单的值替代,缺乏类型检查机制,不包含类型信息,嵌套过多会影响程序的可读性,降低代码的可读性,并且容易出错,导致程序崩溃.那么我们该如何避免因为过多的使用宏定义导致可能出现的问题呢?答案是用全局常量去取代宏定义.
const CGFloat kAnimationDuration = 0.5;
,这么写和宏的作用相同,而且不能对kAnimationDuration的值进行修改,保证了数据的准确性(const保证了值不被修改)
但是这就存在一个问题,定义一个全局常量,其实是可以在整个程序中都能访问的,方法就是用extern关键字(在其他的项目文件中使用extern CGFloat kAnimationDuration;
,这样就可以直接获取到其他文件中定义的全局常量来进行使用),默认情况下,全局常量是不安全的,因为用extern就可以在其他文件进行修改.
若不想被其他文件使用kAnimationDuration的值,或者为了避免造成值污染,就用到了static关键字(声明kAnimationDuration的时候在最前面加static,static const CGFloat kAnimationDuration = 1;
).也就是说使用static以后,创建的全局常量只能在本文件使用了,其他文件是访问不到的.
那么我们再反过头来说一下这个extern CGFloat kAnimationDuration;
,通过这个获取到的其他文件中的常量的值,可是试一下,竟然是可以进行更改的,而且编译不会报错,但是运行试一下,擦,崩溃了.所以为了程序安全,为了避免获取到的这个变量被我们不经意间更改而导致崩溃,我们需extern const kAnimationDuration;
,也就是多加了了一个const
,使获取到的变量变成常量,我们获取的值也就不能再进行修改了.
然后我们再去进行具体分析下const和static
分析之前我们需要先对指针的内容复习下
int a = 10;
int *p = &a;
*p = 20; //a = 20
int b = 30;
p = &b;
*p = 40; //b = 40;
下面开始关于const的研究
const int *p = NULL;//这里的*p不能进行更改,但是p可以进行更改
int const *p = NULL;//效果同上
int const p; //p可以更改,*p不能更改
const int p; //效果同上
int *const p = NULL; //*p可以改,但是p不能进行更改
我们可以得出的结论是,其实主要看的是const的右边是什么,右边是p,则p不能进行修改,右边是*p,则 *p不能进行修改.
下面开始关于static的研究
//写一个循环
for (int i = 0; i < 3; i++) {
test();
}
void test(){
//1.修饰局部变量
//加了static后,让局部变量只初始化一次,局部变量在内存中只有一份内存
//不会改变局部变量的作用域,只会改变其生命周期(直到程序结束,这个局部变量才会被销毁)
static int a = 0;
a++;
NSLog(@"%d",a); //依次输出1,2,3
}
//2.修饰全局变量
//当多个文件都定义了同一个全局变量,当用extern去进行引用的时候,会导致崩溃
//此时,用static就可以把全局变量限制在本文件使用
//所以全局变量建议加static
等等,讲了这么多,好像和最前面将的全局常量代替宏定义有点关系不大啊,跑题了有点,哈哈哈.那么回到正题,如果每次使用都要用extern去引用的话,那岂不是每个文件都要extern一大堆的垃圾代码吗?所以,我最后要说的是我们可以创建一个空的类,来专门进行生命和实现这些代码,和frefixheader文件一样.
// .h文件
extern CGFloat const animationDuration;
// .m文件
static const CGFloat animationDuration = 0.5f;
网友评论