1. const
const意为"常量"。
程序中,"常量"的值是不变的,固定的
-
const用来修饰右边的基本变量或指针变量(基本数据变量p,指针变量*p)
int const *p // *p常量 ;p变量
int * const p // *p变量 ; p常量
const int * const p //p常量;*p常量
int const * const p //p常量;*p常量
注: 判断p 和*p是常量还是变量,关键是看const在谁前面。如果只在p前面,那么p常量,*p还是变量;如果在*p前面,那么*p常量 ,p变量。
-
被修饰的变量只读,不能被修改
- const修饰基本数据变量
//声明一个int类型的变量a,变量初始化值为10,并且变量a左边有一个const关键字修饰 int const a = 10; const int a1 = 10; //两种写法是一样的,const只修饰右边的基本变量,让其只读 //因为变量a被const修饰,就成为了只读,不能被修改赋值了,所以下面这行代码是错误的 //a = 20;//错误代码,编译器报错
-
const修饰指针变量
- const在 * 后时,var变量的内存指针将不能指向其他内存,同时内存块中的内容也将保持不变。
// const在* 后 NSString * const var = @"11"; var = @"12"; // 编译器报错 *var = @"12"; // 编译器报错
- const在 * 前时,var变量的内存指针同样无法指向其他内存块,但是在这种情况下,var的内存块的内存是可以发生变化的。
//内存指针同样无法指向其他内存块 //var的内存块的内存是可以发生变化 NSString const * var = @"11"; *var = @"12"; // 编译器报错 var = @"12"; // 编译器不报错 /* @"" 与[[NSString alloc]init];等价 @[] 与[[NSArray alloc]init];等价 @{} 与[[NSDictionary alloc]init];等价 */ //用字面量语法对一个变量赋值时相当于对他重新开辟了内存块
- const在声明字符串的用法
NSString * const SKYName = @"sky";
-
使用static const修饰变量和宏定义的比较
-
编译时刻:宏是预编译(编译之前处理),const是编译阶段。
-
编译检查:宏不做检查,不会报编译错误,只是替换,const会编译检查,会报编译错误。
-
宏的好处:宏能定义一些函数,方法。 const不能。
-
宏的坏处:使用大量宏,容易造成编译时间久,每次都需要重新替换。
-
在确定了使用的常量类型,及常量值时使用 const 进行定义;而简单的函数,或传参字符串等高级定义时,则使用 define 进行宏定义。
-
2. static
static意为"静态"
-
修饰局部变量
-
让局部变量只初始化一次
-
局部变量在程序中只有一份内存
-
并不会改变局部变量的作用域,仅仅是改变了局部变量的生命周期,也就是说生命周期类似全局变量了,但是作用域不变(只到程序结束,这个局部变量才会销毁)
for (NSInteger i = 0; i < 10; i++) { //声明一个局部变量i NSInteger j = 0; //每次点击view来到这个方法时让i自增 j ++; //打印结果 NSLog(@"j%=ld",j); /* 打印结果 j=1 j=1 j=1 j=1 j=1 j=1 j=1 j=1 j=1 j=1 */ }
- 解释:j一直等于1,这也是预料之中的,因为每次点击进入这个方法就会重新初始化一个全新的变量j = 0,加加了一次后值变为1,然后打印出结果为1,出了这个方法后局部变量j就被释放回收。所以每次打印出来的结果都为1。
for (NSInteger i = 0; i < 10; i++) { //声明一个局部变量i static NSInteger j = 0; //每次点击view来到这个方法时让i自增 j ++; //打印结果 NSLog(@"j%=ld",j); /* 打印结果 j=1 j=2 j=3 j=4 j=5 j=6 j=7 j=8 j=9 j=10 */ }
- 解释:i的值一直在自增。这就是关键字static修饰的局部变量的作用,让局部变量永远只初始化一次,一份内存,生命周期已经跟全局变量类似了,只是作用域不变。
-
-
修饰全局变量
- 全局变量的作用域仅限于当前文件
static SVProgressHUD *sharedView; + (SVProgressHUD*)sharedView { static dispatch_once_t once; #if !defined(SV_APP_EXTENSIONS) dispatch_once(&once, ^{ sharedView = [[self alloc] initWithFrame:[[[UIApplication sharedApplication] delegate] window].bounds]; }); #else dispatch_once(&once, ^{ sharedView = [[self alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; }); #endif return sharedView; }
-
static和const联合使用
static const CGFloat SVProgressHUDParallaxDepthPoints = 10.0f;
static const CGFloat SVProgressHUDUndefinedProgress = -1;
static const CGFloat SVProgressHUDDefaultAnimationDuration = 0.15f;
static const CGFloat SVProgressHUDVerticalSpacing = 12.0f;
static const CGFloat SVProgressHUDHorizontalSpacing = 12.0f;
static const CGFloat SVProgressHUDLabelSpacing = 8.0f;
3. extern
extern意为"外面的、外部的"
-
声明外部全局变量,常与const联合使用
- 声明全局常量
// SVProgressHUD.h //声明一些全局常量 extern NSString * _Nonnull const SVProgressHUDDidReceiveTouchEventNotification; extern NSString * _Nonnull const SVProgressHUDDidTouchDownInsideNotification; extern NSString * _Nonnull const SVProgressHUDWillDisappearNotification; extern NSString * _Nonnull const SVProgressHUDDidDisappearNotification; extern NSString * _Nonnull const SVProgressHUDWillAppearNotification; extern NSString * _Nonnull const SVProgressHUDDidAppearNotification; extern NSString * _Nonnull const SVProgressHUDStatusUserInfoKey;
- 实现全局常量
// SVProgressHUD.m //实现全局常量 NSString * const SVProgressHUDDidReceiveTouchEventNotification = @"SVProgressHUDDidReceiveTouchEventNotification"; NSString * const SVProgressHUDDidTouchDownInsideNotification = @"SVProgressHUDDidTouchDownInsideNotification"; NSString * const SVProgressHUDWillDisappearNotification = @"SVProgressHUDWillDisappearNotification"; NSString * const SVProgressHUDDidDisappearNotification = @"SVProgressHUDDidDisappearNotification"; NSString * const SVProgressHUDWillAppearNotification = @"SVProgressHUDWillAppearNotification"; NSString * const SVProgressHUDDidAppearNotification = @"SVProgressHUDDidAppearNotification"; NSString * const SVProgressHUDStatusUserInfoKey = @"SVProgressHUDStatusUserInfoKey";
extern const与 #define
- #define写法
#define SVProgressHUDDidReceiveTouchEventNotification @"SVProgressHUDDidReceiveTouchEventNotification"
- extern const写法
// SVProgressHUD.h
extern NSString * _Nonnull const SVProgressHUDDidReceiveTouchEventNotification;
// SVProgressHUD.m
NSString * const SVProgressHUDDidReceiveTouchEventNotification = @"SVProgressHUDDidReceiveTouchEventNotification";
-
#define只是简单的替换,又称作宏定义、预处理命令。
-
extern 与const联合使用时,const是要分配内存空间的,提示编译器遇到此变量和函数时在其他模块中寻找其定义
-
#define是不会对数据类型进行检查
-
extern 与const联合使用时,是会对数据类型进行安全检查
-
在shared libraries的情况下,#define(相当于使用@""写法的“字面量”)不能保证得到的字符串地址是一样的。如果用@""的字符串作为dictionary的key的话,会导致它需要做isEqualToString的比较
-
在shared libraries的情况下,用extern NSString * const,只要做指针的比较。显然指针比较比逐个字符比较快多了。
@""写法的字符串会在编译期被替换成NSConstantString的实例,NSString也是唯一一种可以在编译期被实例化的类
网友评论