static关键字
修饰局部变量时:
1、使得局部变量只初始化一次
2、局部变量在程序中只有一份内存
3、局部变量作用域不变,但是生命周期改变了(程序结束才能销毁)
修饰全局变量
1、全局变量的作用域仅限当前文件,外部类是不可以访问到该全局变量的。
默认情况下,全局变量在整个程序中是可以被访问的(即全局变量的作用域是整个项目文件,不导入头文件)
#import "ViewController.h"
static NSString *staticValue2;
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 连续调用两次
[self staticTestA];
[self staticTestA];
// 连续调用两次
[self staticTestB];
[self staticTestB];
// 连续调用两次
[self staticTestC];
[self staticTestC];
}
- (void)staticTestA {
static NSString *staticValue1;
NSLog(@"staticTestA------------%p", &staticValue1);
}
- (void)staticTestB {
static int i = 0;
i++;
NSLog(@"staticTestB------------%d", i);
}
- (void)staticTestC {
int i = 0;
i++;
NSLog(@"staticTestC------------%d", i);
}
@end
打印结果:
2017-12-08 17:25:51.862511+0800 Test[28720:12325782] staticTestA------------0x10f123148
2017-12-08 17:25:51.862617+0800 Test[28720:12325782] staticTestA------------0x10f123148
2017-12-08 17:25:51.862712+0800 Test[28720:12325782] staticTestB------------1
2017-12-08 17:25:51.862785+0800 Test[28720:12325782] staticTestB------------2
2017-12-08 17:25:51.862865+0800 Test[28720:12325782] staticTestC------------1
2017-12-08 17:25:51.862947+0800 Test[28720:12325782] staticTestC------------1
const关键字 被const修饰的变量是只读的
基本数据类型,
int const a = 10; 和const int b = 20; 效果是一样的 只读常量
指针类型
NSString *p;
*p是地址中的值,p是指针地址。
NSString const *p 表示地址中的值没法改变,但是指针的指向可以改变;
而 NSString *const p 表示指针的指向不能改变,但是地址里的内容是可以改变的
extern 外部常量的最佳方法
extern const 关键字,表示这个变量已经声明,只是引用,且不可修改。
小结:1:.m文件中定义的常量,用const修饰代表常量。其中const CGFloat a = 10.f; 和 CGFloat const a = 10.f;两种写法是一样的,都代表a值为常量,不可修改,但是外部可通过extern CGFloat a;引用该变量,若无const,则通过extern引用a后也可修改。全局变量若只想被该文件所持有,不希望被外界引用,则用static修饰,也就是static const CGFloat a = 10.f;和 static CGFloat const a = 10.f;是一样的,注意只有全局变量用static修饰时,才只被该文件所持有,外界不可引用。
const CGFloat XMGRed = 0.4;定义一个常量,若是全局变量,则可被外界引用,但不能修改
2:定义不可变字符串时:用 static NSString * const name = @"JACK";则指针name不可变,外界不可以给该变量赋值。其中const修饰可变与不可变,就看const右边修饰的是什么 例如:NSString * const name = @"JACK",则代表指针name不可变,*name可变,若NSString const * name = @"JACK",则 *name不可变,指针name可变
3:UIKIT_EXTERN:其实就是extern,最好加上const,来告诉外界这个引用变量不可改变。
UIKIT_EXTERN const CGFloat XMGRed;
4:宏定义 与 static const 修饰的全局常量的区别:一般项目中尽量避免使用大量的宏定义,因为每一个宏定义都会在内存中临时开辟一份内存空间,而static const 修饰的常量 ,则只会开启一份内存空间,其使用效果和宏定义相同,建议以后项目开发中定义常量时,多用 static const 来代替宏定义