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";
-
const 與
#define
編譯時刻:
#define
是預編譯(編譯之前處理),const是編譯階段。編譯檢查:
#define
不做檢查,不會報編譯錯誤,只是替換,const會編譯檢查,會報編譯錯誤。#define
的好處:#define
能定義一些函數,方法。 const不能。#define
的壞處:使用大量#define
,容易造成編譯時間久,每次都需要重新替換。在確定了使用的常量類型,及常量值時使用 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;
-
static const 與
#define
-
#define
寫法#define SVProgressHUDParallaxDepthPoints 10.0f
-
static const 寫法
static const CGFloat SVProgressHUDParallaxDepthPoints = 10.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也是唯一一種可以在編譯期被實例化的類