iOS const、宏、static匆笤、extern的關(guān)系

一研侣、const 的介紹和基本使用以及使用場(chǎng)景

  • 1.1、const 簡(jiǎn)介:經(jīng)常使用的字符串常量炮捧,一般是抽成宏庶诡,但是蘋果不推薦我們抽成宏,推薦我們使用const常量咆课。

  • 1.2末誓、const 作用:限制類型

    • const 僅僅用來修飾右邊的變量(基本數(shù)據(jù)變量p,指針變量*p)书蚪,被const修飾的變量是只讀的喇澡。如下
      • const 用法一 (修飾基本變量p)
        不使用const修飾基本變量,允許修改值

        int a = 10;
        a = 12;
        NSLog(@"a=%d",a);
        打印結(jié)果:a=12
        

        使用const修飾基本變量

        //這兩種寫法是一樣的殊校,const只修飾右邊的基本變量 b
        const int b = 5; // b:只讀變量
        int const b = 5; // b:只讀變量
        // 由于b是只讀的晴玖,b無法被修改,入下代碼會(huì)報(bào)錯(cuò)
        b = 3 // 報(bào)錯(cuò)为流,b無法修改
        
      • const 用法二 (修飾指針變量 *p呕屎,帶*的變量,就是 指針變量)
        不使用const修飾指針變量

        // 修飾指針變量 *p敬察,帶 * 的變量秀睛,就是指針變量
        // 定義一個(gè)指向int類型的指針變量,指向a的地址
        a = 12;
        int *p = &a;
        int c = 7;
        p = &c;
        NSLog(@"p=%d",*p);
        打印結(jié)果:p=7
        
        // 由于 p 沒有被修飾莲祸,它訪問 內(nèi)存空間的值 和 指向的地址 都可以被修改允許修改
        *p = 11;
        NSLog(@"p=%d",p);
        打印結(jié)果:p=11
        

        使用 const 修飾指針變量蹂安,const 修飾指針變量訪問的內(nèi)存空間,修飾的是右邊東西,如下 8 種情況來分析

        // 1虫给、2藤抡、4 的效果一樣 都是修飾 const右邊的 *q侠碧,3修飾的是變量 q ,切記 const修飾的是右邊的
        int const *q = 7;   // 1
        const int *q = 7;   // 2
        int * const q = 7;  // 3
        const int *q = 7;   // 4
        // 首先下面的 q 都被修飾抹估,也就是q不能被賦值,然后 * const q 又被 const 修飾
        int const * const q = 7;  // 5
        const int * const q = 7;  // 6
        const int * const q = 7;  // 7
        const int * const q = 7;  // 8
        

        提示:

        • 1弄兜、2药蜻、4 的效果一樣 都是修飾 const右邊的 *q3 修飾的是變量 q ,切記 const 修飾的是右邊的
        • 首先下面的 q 都被修飾替饿,也就是 q 不能被賦值语泽,然后 * const q 又被 const 修飾
  • 1.3、const 的使用場(chǎng)景(場(chǎng)景一用的居多)

    • 場(chǎng)景一:修飾全局變量视卢,目的是:使外界無法修改變量踱卵,保持只讀,提高預(yù)編譯的速度和時(shí)間(蘋果建議使用 const),如下:

      // 設(shè)置基礎(chǔ)的url,這樣來保證base_url的不變(封裝請(qǐng)求的類)
      NSString * const base_url =  @"http://www.baodu.com/";
      
    • 場(chǎng)景二:修飾方法中的參數(shù)惋砂,如下

      -(void)constTest2{
           [self test:@"你好妒挎!"];
           int p = 1;
           [self test1:&p];
           [self test2:2];
      }
      
      // 當(dāng)一個(gè)方法的參數(shù),只讀.
      -(void)test:(NSString * const)string{
           // 這句代碼是報(bào)錯(cuò)的西饵,被 const 修飾過后酝掩,string 是無法被修改的
           string = @"234";
      }
      // 指針只讀,不能通過指針修改值
      - (void)test1:(int const *)a{
           //  *a = 11;
      }
      
      // 基本數(shù)據(jù)類型只讀
      - (void)test2:(int const)a{
      
      }
      

二、宏 的簡(jiǎn)單使用

  • 2.1眷柔、基本概念:宏是一種批量處理的稱謂期虾。一般說來,宏是一種規(guī)則或模式驯嘱,或稱語法替換 镶苞,用于說明某一特定輸入(通常是字符串)如何根據(jù)預(yù)定義的規(guī)則轉(zhuǎn)換成對(duì)應(yīng)的輸出(通常也是字符串)。這種替換在預(yù)編譯時(shí)進(jìn)行宙拉,稱作宏展開宾尚。編譯器會(huì)在編譯前掃描代碼,如果遇到我們已經(jīng)定義好的宏那么就會(huì)進(jìn)行代碼替換谢澈,宏只會(huì)在內(nèi)存中copy一份煌贴,然后全局替換,宏一般分為對(duì)象宏和函數(shù)宏,推薦博客锥忿。

  • 2.2牛郑、宏的弊端:如果代碼中大量的使用宏會(huì)使預(yù)編譯時(shí)間變長(zhǎng)。

  • 2.3敬鬓、常用宏舉例如下

    /** 1淹朋、屏幕的寬高 */
    #define JK_SCREEN_WIDTH  [UIScreen mainScreen].bounds.size.width
    #define JK_SCREEN_HEIGHT  [UIScreen mainScreen].bounds.size.height
    /** 2、判斷是不是蘋果手機(jī) */
    #define JKIs_Iphone (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    
  • 2.4钉答、const與宏的區(qū)別础芍?

    答:1.編譯時(shí)刻 宏:預(yù)編譯 const:編譯;2.編譯檢查 宏沒有編譯檢查数尿,const有編譯檢查仑性;3.宏的好處 定義函數(shù),方法 const不可以右蹦;4.宏的壞處 大量使用宏诊杆,會(huì)導(dǎo)致預(yù)編譯時(shí)間過長(zhǎng)

    提示:

    • 預(yù)編譯:在打開項(xiàng)目的時(shí)候上面會(huì)有一個(gè)加載項(xiàng)目的進(jìn)度條就是預(yù)編譯
    • 編譯:command+R和command+B都是編譯
    • 網(wǎng)上的誤區(qū):大量使用宏,會(huì)導(dǎo)致內(nèi)存暴增(定義一個(gè)字符串的宏何陆,賦值給多個(gè)變量晨汹,打印其內(nèi)存地址,經(jīng)過測(cè)試:宏定義的是常量贷盲,常量都放在常量區(qū)淘这,只會(huì)生成一份內(nèi)存,故網(wǎng)上說的都是不對(duì)的),如下圖
      網(wǎng)上誤區(qū)

三、static 簡(jiǎn)單使用

  • 3.1铝穷、修飾局部變量

    • <1>朦乏、被static修飾局部變量,延長(zhǎng)生命周期氧骤,跟整個(gè)應(yīng)用程序有關(guān)呻疹,程序結(jié)束才會(huì)銷毀,如下:在一個(gè)類的里面打印下面的方法筹陵,只要程序不銷毀, a 的值就不會(huì)被銷毀刽锤,會(huì)一直保持最后一次給 a 賦的值

      -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
      
            static int a = 0;
            ++a;
            NSLog(@"a=%d",a);
      }
      
    • <2>、被 static 修飾局部變量朦佩,只會(huì)分配一次內(nèi)存,如下:從打印結(jié)果我們可以看到并思,a 的內(nèi)存地址不會(huì)再變

      static int a = 0;
      ++a;
      NSLog(@"a = %d a的內(nèi)存地址=%p",a,&a);
      部分打印結(jié)果:
      a = 1   a的內(nèi)存地址=0x10e758160
      a = 2   a的內(nèi)存地址=0x10e758160
      a = 3   a的內(nèi)存地址=0x10e758160
      a = 4   a的內(nèi)存地址=0x10e758160
      

      提示:被static修飾局部變量什么時(shí)候分配內(nèi)存?程序一運(yùn)行就會(huì)給static修飾變量分配內(nèi)存

  • 3.2语稠、修飾全局變量宋彼,被static修飾全局變量,作用域會(huì)修改仙畦,也就是只能在當(dāng)前文件下使用

    #import "ViewController.h"
    
    static int b = 20;
    
    @interface ViewController ()
    
    @end
    
    @implementation TestViewController
    
    - (void)viewDidLoad {
         [super viewDidLoad];
    
        self.view.backgroundColor = [UIColor purpleColor];;
    }
    @end
    

四输涕、extern 簡(jiǎn)單使用

  • 4.1、聲明外部全局變量(只能用于聲明慨畸,不能用于定義)莱坎,舉例如下:我們?cè)陬惱锩娑x的全局變量,在其他的類里面使用的時(shí)候只要聲明一下就好

    #import "ViewController.h"
    int x = 20;
    
    @interface ViewController ()
    
    @end
    
    @implementation TestViewController
    
    - (void)viewDidLoad {
          [super viewDidLoad];
    
          self.view.backgroundColor = [UIColor purpleColor];;
    }
    @end
    

    在其他類里面使用一寸士,如下:聲明一下即可

    #import "TestViewController.h"
    
    @interface TestViewController ()
    
    @end
    
    @implementation TestViewController
    
    - (void)viewDidLoad {
          [super viewDidLoad];
    
          self.view.backgroundColor = [UIColor purpleColor];;
    }
    
    extern int x;
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
         NSLog(@"x的值是:%d",x);
         // 打印結(jié)果: x的值是:20
    }
    @end
    

    在其他類里面使用二檐什,如下:在ViewController類的.h里面聲明一下即可,如下:

    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController
    
    extern int x;
    
    @end
    
  • 4.2弱卡、extern工作原理:先會(huì)去當(dāng)前文件下查找有沒有對(duì)應(yīng)全局變量乃正,如果沒有,才會(huì)去其他文件查找

五婶博、static 與 const 聯(lián)合使用

  • 5.1瓮具、回顧一下 static 與 const
    const:修飾全局變量
    static:修飾全局變量,修改作用域

  • 5.2凡蜻、static 與 const 聯(lián)合使用
    如果我們想這個(gè) BASE_URL無法被其他類使用搭综,那么我們就在前面加上 static 因?yàn)?static 修飾全局變量垢箕,修改作用域划栓,只能在 UrlTest里面使用,再其他類里面使用是不可以的,切記:這個(gè) BASE_URL 是在 .m 里面定義的

    #import "UrlTest.h"
    
    static NSString * const BASE_URL  =  @"http://www.baodu.com/";
    
    @implementation UrlTest
    
    @end
    

六条获、extern 與 const 聯(lián)合使用

  • 6.1忠荞、開發(fā)中使用場(chǎng)景:在多個(gè)文件中經(jīng)常使用的同一個(gè)字符串常量,可以使用extern與const組合。原因入下:

    • static與const組合:在每個(gè)文件都需要定義一份靜態(tài)全局變量委煤。
    • extern與const組合:只需要定義一份全局變量堂油,多個(gè)文件共享。

    提示:開發(fā)中便于管理所有的全局變量碧绞,通常搞一個(gè)Global文件府框,里面專門定義全局變量,統(tǒng)一管理讥邻,要不然項(xiàng)目文件太多不好找迫靖。

  • 6.2、extern的基本使用 :當(dāng)我們?cè)谝粋€(gè)防止一個(gè)變量被修改的時(shí)候兴使,我們?cè)谇懊婕由?const,如下,僅僅是 BASE_URL無法被修改系宜,在自己的.h文件里面 extern 聲明一下即可,在其他類里面通過 導(dǎo)入 .h 文件发魄,還是可以使用的 BASE_URL

    • UrlTest的.h文件 ( 聲明 BASE_URL )

      #import "UrlTest.h"
      // 聲明  BASE_URL
      extern NSString * const BASE_URL;
      
      @implementation UrlTest
      
      @end
      
    • UrlTest的.m文件

      #import "UrlTest.h"
      
      NSString * const BASE_URL  =  @"http://www.baodu.com/";
      
      @implementation UrlTest
      
      @end
      

      提示:定義全局的東西盹牧,遵循規(guī)定,頂一個(gè)以全局的文件來管理全局變量励幼,以避免全局變量重復(fù)定義

  • 6.3汰寓、extern 的高級(jí)使用 (模仿 YYKIT 的使用 ),其實(shí)它只是把蘋果的宏拿過來改改名字,看起來很牛逼苹粟,我們也可以牛逼一下踩寇,如下:

    • 蘋果的定義:

      #ifdef __cplusplus
      #define UIKIT_EXTERN     extern "C" __attribute__((visibility ("default")))
      #else
      #define UIKIT_EXTERN         extern __attribute__((visibility ("default")))
      #endif
      
    • 我們只需要把 UIKIT_EXTERN 改為 JKKIT_EXTERN,那以后我們就可以使用我們自己定義的

      #ifdef __cplusplus
      #define JKKIT_EXTERN        extern "C" __attribute__((visibility ("default")))
      #else
      #define JKKIT_EXTERN            extern __attribute__((visibility ("default")))
      #endif
      
    • 蘋果和我們自己定義的使用如下

      #import <Foundation/Foundation.h>
      #import <UIKit/UIKit.h>
      
      #ifdef __cplusplus
      #define JKKIT_EXTERN        extern "C" __attribute__((visibility ("default")))
      #else
      #define JKKIT_EXTERN            extern __attribute__((visibility ("default")))
      #endif
      
      // 使用自己定義的
      JKKIT_EXTERN NSString * const BASE_URL;
      // 使用蘋果定義的 UIKIT_EXTERN
      // UIKIT_EXTERN NSString * const BASE_URL;
      
      NS_ASSUME_NONNULL_BEGIN
      
      @interface UrlTest : NSObject
      
      @end
      
      NS_ASSUME_NONNULL_END
      
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市六水,隨后出現(xiàn)的幾起案子俺孙,更是在濱河造成了極大的恐慌,老刑警劉巖掷贾,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件睛榄,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡想帅,警方通過查閱死者的電腦和手機(jī)场靴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來港准,“玉大人旨剥,你說我怎么就攤上這事∏掣祝” “怎么了轨帜?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)衩椒。 經(jīng)常有香客問我蚌父,道長(zhǎng)哮兰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任苟弛,我火速辦了婚禮喝滞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘膏秫。我一直安慰自己右遭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布缤削。 她就那樣靜靜地躺著狸演,像睡著了一般。 火紅的嫁衣襯著肌膚如雪僻他。 梳的紋絲不亂的頭發(fā)上宵距,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音吨拗,去河邊找鬼满哪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛劝篷,可吹牛的內(nèi)容都是我干的哨鸭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼娇妓,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼像鸡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起哈恰,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤只估,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后着绷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛔钙,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年荠医,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吁脱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡彬向,死狀恐怖兼贡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情娃胆,我是刑警寧澤遍希,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站缕棵,受9級(jí)特大地震影響孵班,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜招驴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一篙程、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧别厘,春花似錦虱饿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至冗懦,卻和暖如春爽冕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背披蕉。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工颈畸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人没讲。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓眯娱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親爬凑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子徙缴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容