iOS所有變量(static/extren/const等)

眼看就要過年了米苹,這兩天卻著著實實被全局變量坑了一把,APP開發(fā)者和我們SDK使用了相同的全局變量導致嵌碼沖突烙懦。還好只是公司內部APP嵌碼發(fā)現(xiàn)的問題驱入,沒有交付給大客戶。否則氯析,恐怕要被客戶和經(jīng)理批的狗血臨頭亏较,學藝不精也怨不了誰。今天就結合第三方以及自身的理解詳細分析一下iOS的包含的所有變量掩缓,上圖:


變量.png

下面我命就詳細分析各個變量的使用:

一雪情、static靜態(tài)變量

靜態(tài)變量優(yōu)點:

1、節(jié)省內存你辣。靜態(tài)變量只存儲一處巡通,但供所有對象使用尘执。
2、它的值是可以更新的宴凉。
3誊锭、可提高時間效率。只要某個對象對靜態(tài)變量更新一次弥锄,所有的對象都能訪問更新后的值丧靡。

靜態(tài)變量static的使用

1、修飾局部變量
讓局部變量只初始化一次籽暇,局部變量在程序中只有一份內存温治,但是并不會改變局部變量的作用域,僅僅是改變了局部變量的生命周期(只到程序結束戒悠,這個局部變量才會銷毀)熬荆。

2、修飾全局變量
全局變量的作用域僅限于當前文件

3绸狐、static作用于函數(shù):e.g.: static void func(void);
  使用static用于函數(shù)定義時卤恳,對函數(shù)的連接方式產(chǎn)生影響,使得函數(shù)只在本文件內部有效六孵,對其他文件是不可見的纬黎。這樣的函數(shù)又叫作靜態(tài)函數(shù)。使用靜態(tài)函數(shù)的好處是劫窒,不用擔心與其他文件的同名函數(shù)產(chǎn)生干擾本今,另外也是對函數(shù)本身的一種保護機制。
  如果想要其他文件可以引用本地函數(shù)主巍,則要在函數(shù)定義時使用關鍵字extern冠息,表示該函數(shù)是外部函數(shù),可供其他文件調用孕索。另外在要引用別的文件中定義的外部函數(shù)的文件中逛艰,使用extern聲明要用的外部函數(shù)即可。

  • 重點:也就是說搞旭,static定義的方法和或者變量最多也不會超出所在文件散怖,也就是所在類。如果要其他類引用次靜態(tài)方法肄渗,那么就必須要extern聲明引用镇眷。
static int age = 20;//全局變量
static NSString *name = @"zhang";
- (void)staticTest{
    // static修飾局部變量,將全局變量變成局部變量翎嫡,但是在其他地方全局變量還是不變的
    static int age = 0;
    age++;
    //所以此處輸入的是局部變量的值欠动,在其他部分調用全局age還是20.
    NSLog(@"局部變量的age:%d",age);
}
常見的使用場景:
1)最常見的就是Cell復用的CellIdentifier設置都是定義為靜態(tài)的字符串。(就是為了節(jié)省內存和提高時間效率)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
        return cell;
}
2)單例創(chuàng)建
+ (AccountManager *)sharedManager
{
    static AccountManager *sharedAccountManagerInstance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        sharedAccountManagerInstance = [[self alloc] init];
    });
    return sharedAccountManagerInstance;
}
extern修飾全局變量
  • extern作用域為整個源程序,在Reachability.h中具伍,extern配合const設置了一個的全局且不可變的變量翅雏,如下:
#ifndef NS_ENUM
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#endif
//設置全局且不可變變量kReachabilityChangedNotification,在Reachability.m中賦值
extern NSString *const kReachabilityChangedNotification;

extern配合const設置要特別注意一點人芽,那就是變量的命名一定要有特殊性望几,在多人開發(fā)過程中防止定義相同導致的沖突,如下圖:


重復的標識.png

所以啼肩,使用全局變量要慎重橄妆,而且代碼要規(guī)范衙伶,避免不必要的坑祈坠。

  • extern與const聯(lián)合使用:
    static與const組合:在每個文件都需要定義一份靜態(tài)全局變量。
    extern與const組合:只需要定義一份全局變量矢劲,多個文件共享赦拘。

  • extern作用:
    只是用來獲取全局變量(包括全局靜態(tài)變量)的值,不能用于定義變量
    extern工作原理:
    先在當前文件查找有沒有全局變量芬沉,沒有找到躺同,才會去其他文件查找。

- (void)externAndConst{
    /*
     一般會先新建.h文件專門存放常量的引用丸逸,在iOS的網(wǎng)絡判斷Reachbility中就有蹋艺。
     注意一定要在.h文件中定義,否則會報錯黄刚。
     */
//    extern NSString *const kReachabilityChangedNotification;
//    extern const int num;
    
    
    //逼格更高的一種寫法捎谨,模仿系統(tǒng)UIKIT_EXTERN來替代extern
//    UIKIT_EXTERN NSString *const kReachabilityChangedNotification;
//    UIKIT_EXTERN const int num;
    
    /*
     在.m file中進行賦值專門存放static const修飾的變量,需要用的時候導入頭文件就可以了憔维。
     定義整個程序都能訪問的常量
     */
   
    const int num = 666;
    NSString *const kReachabilityChangedNotification = @"kReachabilityChangedNotification";

}

在AFNetWorking中也有使用extern涛救,這里作為一個擴展,截圖如下:

定義全局變量.png

extern的使用.png

三业扒、局部變量

此處的i就是局部變量检吆,僅僅作用在這個for循環(huán)方法內部。

 for (int i = 0; i < array.count; i ++) {
        NewsTableViewController *pulicVc = [[NewsTableViewController alloc]init];
        pulicVc.title = array[i];
        [self addChildViewController:pulicVc];
    }

四程储、實例變量

下面為實例變量蹭沛,作用域為整個類。

@property (nonatomic,copy) NSString *number;      //數(shù)量章鲤,被操作對象的某個序號指標摊灭,如:文章字數(shù)
@property (nonatomic,copy) NSString *objectName;  //對象短名稱,如:文章標題
@property (nonatomic,copy) NSString *objectIDs;   //對象IDs  統(tǒng)計列表中多個文章的ID時傳值

五咏窿、const變量值不可變

我們設置不可變參數(shù)noChange斟或,然后兩次賦值,如下圖所示集嵌,我們在賦值一次之后萝挤,第二次想要改變noChange的值的時候報錯:


代碼效果1.png

代碼效果2.png
1御毅、使用static const修飾變量和宏定義的比較
  • 相同點:
    a:都不能再被修改
    b:一處修改,其他地方都改不了
  • 不同點:
    a:static const 修飾變量只有一份內存
    b:宏定義只是簡單的替換怜珍,每次使用都需要創(chuàng)建一份內存端蛆。
2、結論:

使用static const修飾更加高效酥泛,在同一個文件內可以使用static const取代#define
static const聲明一個靜態(tài)的全局只讀常量

3今豆、使用場景:

在一個文件中經(jīng)常使用的字符串常量,可以使用static與const組合柔袁,可用于替換#define

const和宏的區(qū)別:

const簡介:之前常用的字符串常量呆躲,一般是抽成宏,但是蘋果不推薦我們抽成宏捶索,推薦我們使用const常量插掂。

  • 編譯時刻:宏是預編譯(編譯之前處理),const是編譯階段腥例。
  • 編譯檢查:宏不做檢查辅甥,不會報編譯錯誤,只是替換燎竖,const會編譯檢查璃弄,會報編譯錯誤。
  • 宏的好處:宏能定義一些函數(shù)构回,方法夏块。 const不能。
  • 宏的壞處:使用大量宏捐凭,容易造成編譯時間久拨扶,每次都需要重新替換。
/*
 二茁肠、const 使用
 */
- (void)constTest{
    /*
     1患民、沒有const修飾的指針。指針p和*p都能夠被修改垦梆。
     */
    // 定義一個指針變量
    int *p = NULL;
    
    // 定義2個int類型的變量
    int a = 10;
    int b = 30;
    
    // p指向a
    p = &a;
    *p = 20;
    
    // p指向b
    p = &b;
    *p = 40;
    
    NSLog(@"%d %d", a, b);
    
    /*
     2匹颤、const修飾的*m,只能被賦值一次托猩,若再次被賦值印蓖,編譯器會報錯。
     const int *m = NULL;
     *m = 20;
     */
  
    
    /*
      3京腥、const修飾的m,被const修飾的n只能存一次地址赦肃,以后再也不能存其它地址了,否則編譯器報錯
    const修飾的指針變量n
     int * const n = NULL;
     int c = 20;
     n = &c; // 編譯器報錯,不能修改指針變量n
     */
    
    
    /*
     4他宛、const聲明字符串的用法船侧,只能賦值一次,再次賦值會出錯厅各。
     */
    NSString *const name = @"sam";
    
    
    
}

//三镜撩、static&Const聯(lián)合使用
- (void)staticAndConst{
    
    /*
     1、static將一個全局變量變成局部變量
     2队塘、const將一個局部變量變成局部常量
     */
    // 定義了一個局部常量,只能被賦值一次袁梗,無法再次改變。
    static const CGFloat ZMJRed = 0.4;
    static const CGFloat ZMJGreen = 0.6;
    static const CGFloat ZMJBlue = 0.7;
    
    NSLog(@"---------ZMJRed:%f------ZMJGreen:%f------ZMJBlue:%f",ZMJRed,ZMJGreen,ZMJBlue);
}

//四憔古、static const 與#define 比較
- (void)staticConstAndDefine{
    /*
     1遮怜、使用static const修飾變量和宏定義的比較
     相同點:
     a:都不能再被修改
     b:一處修改,其他地方都改不了
     不同點:
     a:static const 修飾變量只有一份內存
     b:宏定義只是簡單的替換投放,每次使用都需要創(chuàng)建一份內存奈泪。
     
     2、結論:
     使用static const修飾更加高效灸芳,在同一個文件內可以使用static const取代#define
     static const聲明一個靜態(tài)的全局只讀常量
     3、使用場景:
     在一個文件中經(jīng)常使用的字符串常量拜姿,可以使用static與const組合烙样,可用于替換#define
     */
    
    /*
     const和宏的區(qū)別:
    const簡介:之前常用的字符串常量,一般是抽成宏蕊肥,但是蘋果不推薦我們抽成宏谒获,推薦我們使用const常量。
    
    編譯時刻:宏是預編譯(編譯之前處理)壁却,const是編譯階段批狱。
    編譯檢查:宏不做檢查,不會報編譯錯誤展东,只是替換赔硫,const會編譯檢查,會報編譯錯誤盐肃。
    宏的好處:宏能定義一些函數(shù)爪膊,方法。 const不能砸王。
    宏的壞處:使用大量宏推盛,容易造成編譯時間久,每次都需要重新替換谦铃。
    */
    
    
    //1耘成、static const 修飾變量只有一份內存
    static const CGFloat ZMJBlue = 0.4;
    //2、只是用0.4替換ZMJRed  define每次使用都會創(chuàng)建一份內存,所以效率不如static const
    #define ZMJRed @"zhangsanlisi"
   
    NSString *str = ZMJRed;
    NSString *str1 = ZMJRed;
    NSLog(@"---str:%p-------str1:%p",str,str1);
#warning 但是引用的define的時候并沒有創(chuàng)建內存啊瘪菌,莫名其妙
    
    // 3件豌、開發(fā)中經(jīng)常拿到key修改值,因此用const修飾key,表示key只讀控嗜,不允許修改茧彤。
    static  NSString * const key = @"name";
    
    // 4、如果 const修飾 *key1,表示*key1只讀疆栏,key1還是能改變曾掂。
    
    static  NSString const *key1 = @"name";
    NSLog(@"修改前:%@",key);

    key1 = @"zhangsanfang";
    NSLog(@"相親們,修改后沒毛脖诙ァ:%@",key1);
    
//    2018-02-09 14:36:06.617239+0800 OCVariableDemo[4842:891035] --------static1:0x107083970-------static2:0x107083970
//    2018-02-09 14:36:06.617341+0800 OCVariableDemo[4842:891035] --------define:0x608000052000-------define:0x608000052000
}

六珠洗、volatile變量值隨時可變

volatile參數(shù)可以隨時改變,目前沒有找到使用的地方若专,以后遇到的話會補充上來噠许蓖。

參考知識點:http://blog.csdn.net/hdfqq188816190/article/details/51435268,感謝作者“崢吖”的分享调衰,本人在此基礎上做了些補充并寫了Demo供大家查閱膊爪,如有不足之處還望指出。
Demo鏈接:https://github.com/caiqingchong/BianLiang

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末米酬,一起剝皮案震驚了整個濱河市趋箩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌叫确,老刑警劉巖跳芳,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異竹勉,居然都是意外死亡飞盆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門饶米,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桨啃,“玉大人,你說我怎么就攤上這事檬输≌振” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵丧慈,是天一觀的道長析命。 經(jīng)常有香客問我主卫,道長,這世上最難降的妖魔是什么鹃愤? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任簇搅,我火速辦了婚禮,結果婚禮上软吐,老公的妹妹穿的比我還像新娘瘩将。我一直安慰自己,他們只是感情好凹耙,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布姿现。 她就那樣靜靜地躺著,像睡著了一般肖抱。 火紅的嫁衣襯著肌膚如雪备典。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天意述,我揣著相機與錄音提佣,去河邊找鬼。 笑死荤崇,一個胖子當著我的面吹牛拌屏,可吹牛的內容都是我干的。 我是一名探鬼主播天试,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼槐壳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了喜每?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤雳攘,失蹤者是張志新(化名)和其女友劉穎带兜,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吨灭,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡刚照,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了吠冤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡郭变,死狀恐怖诉濒,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情未荒,我是刑警寧澤片排,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布划纽,位于F島的核電站,受9級特大地震影響靖避,放射性物質發(fā)生泄漏。R本人自食惡果不足惜病附,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦沛善、人聲如沸塞祈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽产捞。三九已至轧葛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尿扯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留辟宗,地道東北人泊脐。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像秕铛,于是被迫代替她去往敵國和親但两。 傳聞我的和親對象是個殘疾皇子谨湘,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,102評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)续担,斷路器赤拒,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 基弗冷蚂?Nonono蝙茶,就愛“舞女控”印象大師埃德加·德加 文章作者:藝厘米 安塞姆·基弗 【成長于第三帝國廢墟中的跨...
    藝厘米artcm閱讀 360評論 0 0
  • 每次打開對話框隆夯,趁著有什么高興的事想跟你分享下或者趁著節(jié)假日問候你下蹄衷,也有時只是突然太想念愧口,想跟你聊聊。 但每次盯...
    f220a6e26e90閱讀 258評論 0 0
  • 成功的基礎是態(tài)度,態(tài)度決定了狀態(tài)大咱,狀態(tài)決定了效率碴巾,效率決定了成敗厦瓢! 核心就是沒有不可能煮仇,只是自己給自己設限浙垫!凡事找...
    力拓閱讀 829評論 0 1