在iOS開發中會常常使用到static
const
extern
3個關鍵字, 一直對這3個關鍵字很模糊, 這裏總結一下, 作一個筆記.bash
const一般被用來修飾字符串常量, 其做用和宏相似.函數
宏定義是預編譯指令, 在編譯以前處理, 宏不作檢查不會報編譯錯誤, 只是簡單的替換. const會編譯階段, 會作編譯檢查報編譯錯誤.ui
宏能夠用來定義一些函數和方法, 而const只能用來定義變量常量. 在項目中大量使用宏定義, 會使項目的編譯時長大大增長.spa
NSString * const a = @"123";
複製代碼
a的值是沒法修改的.3d
const實際上是編譯器特性, 那麼咱們如何去理解const呢?code
int a = 10;
int b = 20;
int main(int argc, const char * argv[]) {
@autoreleasepool {
int c = a;
c = b;
}
return 0;
}
複製代碼
經過對上訴代碼反彙編以下:cdn
將變量b修改成const修飾, 代碼以下blog
int a = 10;
int const b = 20;
int main(int argc, const char * argv[]) {
@autoreleasepool {
int c = a;
c = b;
}
return 0;
}
複製代碼
對上訴代碼進行反彙編, 以下:內存
對比兩次反彙編的代碼, 變量a存儲在數據段全局區, 而對變量b進行const修飾之後, 變量b直接被替換爲當即數$0x14(也就是十進制的20), 因此被const修飾之後, 變量b的值就不能修改了.作用域
static關鍵字用來修飾變量的做用域. static修飾的變量只會分配一分內存.
static修飾局部變量, 在上一次修改的基礎上進行修改
-(void)staticDemo1
{
int a2 = 0
static int a1 = 0;
a1++;
NSLog(@"%zd", a1);
}
複製代碼
局部變量a2的內存分佈在棧上, 而靜態變量a1的內存是分佈在數據段的全局區, 沒執行一次staticDemo1方法變量a2的值都被從新賦值爲0, 而a1在常量區, 內存地址不會發生變化, 仍是取的以前賦的值
不管調用幾回方法, a1的內存只有一份, 屢次被調用時a1是在原來的基礎上修改的. 輸出結果爲 1 2 3
static修飾全局變量, 在當前文件中可用, 在不一樣函數中調用修改, 會在上一個函數的基礎上修改
static int a2 = 3;
- (void)viewDidLoad {
[super viewDidLoad];
[self staticDemo2];
[self staticDemo3];
[self staticDemo2];
[self staticDemo3];
}
-(void)staticDemo2
{
a2++;
NSLog(@"%zd", a2);
}
-(void)staticDemo3
{
a2++;
NSLog(@"%zd", a2);
}
複製代碼
結果: 4 5 6 7
靜態全局變量和非靜態全局變量的區別: static限制了變量的做用域爲當前文件, 其餘文件能夠定義一個相同的static變量, 若是沒有static修飾, 在其餘文件中定義了相同名稱的全局變量, 會報錯.
思考: 爲何在不一樣的文件中用static定義相同名稱的變量, 不會報重複定義的錯誤呢?
猜測: 用static定義相同名稱的變量, 被分佈到數據段全局區不一樣內存地址上.
在main函數中執行下列函數, 爲了獲取static int a
變量的地址, 在函數中將的值賦值給一個局部變量.
#include "StaticTest.h"
static int a = 10;
int main(int argc, const char * argv[]) {
@autoreleasepool {
int c = a;
staticTest();
}
return 0;
}
複製代碼
在StaticTest.c
中定義以下函數
static int a = 20;
void staticTest() {
int b = a;
}
複製代碼
分別在int c = a
和int b = a
處打斷點, 查看彙編代碼以下:
經過查看彙編, 計算出a變量的地址分別爲0x100001028
和0x10000102C
, 查看這兩個地址存放的數據.
只能用來獲取全局變量的值, 不能用於定義變量
static和const
static NSString * const name = @"OneAlon";
複製代碼
extern和const, 在多個文件中常常使用的字符串常量, 一般建立一個GlobeConst文件用於管理全局變量, 統一管理.
@interface GlobeConst : NSObject
extern NSString * const nameKey;
@end
------------------------------------------
@implementation GlobeConst
NSString * const nameKey = @"OneAlon";
@end
複製代碼