iOS const,static,extern,宏

1.const (常量)

const的作用和宏是很類似的伪煤,當(dāng)有字符串常量的時(shí)候,蘋(píng)果推薦我們使用const宾袜,蘋(píng)果經(jīng)常把常用字符串定義成const狰右。
const僅僅用來(lái)修飾右邊的變量(基本數(shù)據(jù)變量p,指針變量*p秸讹,對(duì)象變量)
被const修飾的變量是只讀的且是全局的檀咙。

const 與宏的區(qū)別

 1.編譯時(shí)刻 : const: 編譯時(shí)刻 ,  宏:預(yù)編譯
 2.編譯檢查: const  會(huì)檢查錯(cuò)誤 , 宏: 不會(huì)檢查錯(cuò)誤
 3.宏的好處: 可以定義代碼
 4.宏的壞處: 編譯時(shí)間過(guò)長(zhǎng), 因此常用的字符串通常使用 const修飾
 注意:很多博客說(shuō)宏使用的多了會(huì)造成內(nèi)存不斷增加,每次都會(huì)分配一個(gè)內(nèi)存, 打印地址可以驗(yàn)證

const 作用:

 1.僅僅是用來(lái)修飾右邊的變量(只能修飾變量:基本變量,指針變量,對(duì)象變量)
 2.const修飾的變量表示只讀
    int * const p; // p:只讀 *p:變量
    const int *p1; // *p1:只讀 p1:變量
    int const *p2; // *p2:只讀 p2:變量
    int const * const p3; // *p3:只讀 p3:只讀
    const int  * const p4; // *p4:只讀 p4:只讀

2.static

static作用

 1.修飾局部變量 
   * 延長(zhǎng)這個(gè)局部變量的生命周期,只要成員運(yùn)行,局部變量就會(huì)一直存在 
   * 局部變量只會(huì)分配一次內(nèi)存,為什么?用 static修飾的代碼,只會(huì)在程序一啟動(dòng),就會(huì)執(zhí)行,以后就不會(huì)再執(zhí)行 
 2.修飾全局變量 
   * 只會(huì)修改全局變量的作用域,表示會(huì)只能是當(dāng)前文件使用

static修飾變量注意點(diǎn)

用于定義一個(gè)內(nèi)部全局變量
為了提高數(shù)據(jù)的安全性, 不讓別人在其它文件中修改我們的全局變量
只要用static修改的全局變量就是內(nèi)部全局變量, 只能在當(dāng)前文件中使用
如果多個(gè)文件中存在同名的內(nèi)部全局變量, 相互不會(huì)影響
如果既有外部全局變量也有內(nèi)部全局變量, 那么會(huì)優(yōu)先訪問(wèn)內(nèi)部全局變量

3.extern

作用:

extern主要是用來(lái)引用全局變量,它的原理就是先在本文件中查找璃诀,本文件中查找不到再到其他文件中查找弧可。
用于聲明一個(gè)外部全局變量,聲明變量是其他文件的外部變量劣欢。
不能定義變量
聲明只需要在使用變量之前聲明就可以了

聲明和定義的區(qū)別:(聲明不會(huì)開(kāi)辟存儲(chǔ)空間,定義會(huì)開(kāi)辟存儲(chǔ)空間)
注意:UIKIT_EXTERN == extern

總結(jié):

  • 在iOS開(kāi)發(fā)中請(qǐng)盡量多使用const僻焚、enum來(lái)代替宏定義(#define),隨著項(xiàng)目工程的逐漸增大,過(guò)多的宏定義還可能影響項(xiàng)目的編譯速度扰付。

  • 為何不將上面常量直接導(dǎo)入pch文件?
    蘋(píng)果不建議使用pch颊埃,pch的原理是將其中定義的宏或全局常量/變量等copy到每個(gè)執(zhí)行文件(.m文件), 如果在其中定義全局常量, 則會(huì)報(bào)重復(fù)定義全局常量錯(cuò)誤.

  • iOS項(xiàng)目中經(jīng)常會(huì)用到一些常量字符串,如果單獨(dú)的在一個(gè).m中使用牧抵,可以用宏定義笛匙,可以用static + const 來(lái)規(guī)定一個(gè)字符串侨把,比如最常用的cell的reuserID,一般我們很少會(huì)用到宏來(lái)修飾妹孙,因?yàn)楹瓴蛔鰴z查秋柄,不會(huì)報(bào)編譯錯(cuò)誤,而且預(yù)編譯的時(shí)候蠢正,會(huì)延長(zhǎng)編譯時(shí)間骇笔,蘋(píng)果也不推薦我們大量的使用宏。

  • 查閱到很多第三方庫(kù)和類似的蘋(píng)果的用法嚣崭,可以看到笨触,很多加以區(qū)分的const字符串都會(huì)寫(xiě)到一個(gè)專門使用的類中,比如MJRefresh的MJRefreshConst.h 和 MJRefreshConst.m有鹿,這種寫(xiě)法有很多好處旭旭,其中之一就是:在規(guī)定全局變量,并且在其他地方引用的時(shí)候葱跋,容易造成字符串重復(fù)的問(wèn)題持寄,特別是在協(xié)同開(kāi)發(fā)的過(guò)程中。因此娱俺,管理人員都是會(huì)規(guī)定好一個(gè)類來(lái)專門的管理這些 只讀字符串 稍味,也就是MJRefreshConst 或者是上面的Const,這樣的話荠卷,在引用過(guò)程中模庐,直接import這個(gè)類就可以使用了,避免了很多不必要的麻煩油宜。
    使用注釋加以區(qū)分的話掂碱,能夠把這些字符串分類管理,更加提高團(tuán)隊(duì)工作效率慎冤。

用法總結(jié):
 1. 在函數(shù)外疼燥,直接定義對(duì)象,不需要額外添加修飾符蚁堤,對(duì)象可被修改醉者; 一般形式的全局變量
 2. 只用static修飾,對(duì)象可以被修改披诗,但是生命周期在APP運(yùn)行期撬即; 用static修飾就是靜態(tài)變量(也叫全局靜態(tài)變量),不用static修飾的就是全局非靜態(tài)變量呈队;
 修飾局部變量:讓局部變量只初始化一次剥槐;局部變量在程序中只有一份內(nèi)存;并不會(huì)改變局部變量的作用域宪摧,僅僅是改變了局部變量的生命周期(只到程序結(jié)束才沧,這個(gè)局部變量才會(huì)銷毀)
 修飾全局變量:全局變量的作用域僅限于當(dāng)前文件
 
 3. 用const修飾:一般不定義在本文件內(nèi)迈喉,字符串可以被修改,也可以不被修改(主要)温圆;用const修飾的就是常量;全局非靜態(tài)/靜態(tài)常量
 4. 用static孩革,const一起修飾:全局靜態(tài)常量岁歉,在本文件內(nèi)字符串可以被修改,也可以不被修改(主要)膝蜈;

 常用的三種:
 1. static 修飾全局靜態(tài)變量锅移,比如cell的標(biāo)識(shí)符
 2. static+const在本文件內(nèi)使用,修飾不可變字符串饱搏,全局靜態(tài)常量
 3. const在單獨(dú)一個(gè)文件內(nèi)使用非剃,修飾字符串,變成不可變的常量推沸。
 */

4. 宏

宏的常見(jiàn)用法(常見(jiàn)字符串抽成宏,常見(jiàn)代碼抽成宏)當(dāng)有字符串常量的時(shí)候备绽,蘋(píng)果推薦我們使用const,蘋(píng)果經(jīng)常把常用字符串定義成const

宏與const的區(qū)別:

編譯時(shí)刻:宏是預(yù)編譯(編譯之前處理)鬓催,const是編譯階段肺素。
編譯檢查:宏不做檢查,不會(huì)報(bào)編譯錯(cuò)誤宇驾,只是替換倍靡,const會(huì)編譯檢查,會(huì)報(bào)編譯錯(cuò)誤课舍。
宏的好處:宏能定義一些函數(shù)塌西,方法。 const不能筝尾。
宏的壞處:使用大量宏捡需,容易造成編譯時(shí)間久,每次都需要重新替換忿等。
注意:swift中, 蘋(píng)果已經(jīng)將宏殺掉, 所以項(xiàng)目開(kāi)發(fā)中, 須用const代替宏.

宏定義:

//注意:
//1.宏名和參數(shù)列表之間不能有空格栖忠,否則空格后面的所有字符串都作為替換的字符串。
//2.帶參數(shù)的宏在展開(kāi)時(shí)贸街,只作簡(jiǎn)單的字符和參數(shù)的替換庵寞,不進(jìn)行任何計(jì)算操作。所以在定義宏時(shí)薛匪,一般用一個(gè)小括號(hào)括住字符串的參數(shù)捐川。并且計(jì)算結(jié)果最好也括起來(lái)防止錯(cuò)誤。


#define NAME @"henry"  //不帶參數(shù)的宏定義 (格式: #define 標(biāo)示符 字符串(“字符串”可以是常數(shù)逸尖、表達(dá)式古沥、格式串等瘸右。)宏名的有效范圍是從定義位置到文件結(jié)束。如果需要終止宏定義的作用域岩齿,可以用#undef命令太颤。)
#define average(a, b) (a+b)/2 //帶參數(shù)的宏定義:(對(duì)帶參數(shù)的宏,在調(diào)用中,不僅要宏展開(kāi),而且要用實(shí)參去代換形參。格式:#define 宏名(形參表) 字符串)
//條件編譯后面的條件表達(dá)式中不能識(shí)別變量,它里面只能識(shí)別常量和宏定義
#define SCORE 67
#if SCORE > 90
    //("優(yōu)秀\n");
#elif SCORE > 60
    //NSLog("良好\n");
#else
    //NSLog("不及格\n");
#endif

#ifdef MACRO_Define  // 如果已定義MACRO_Define這個(gè)宏
    //代碼塊1
#else
    //代碼塊2
#endif

5. 結(jié)構(gòu)體盹沈,枚舉(typeof與typedef)

typeof 是一個(gè)一元運(yùn)算龄章,放在一個(gè)運(yùn)算數(shù)之前,運(yùn)算數(shù)可以是任意類型乞封∽鋈梗可以理解為:我們根據(jù)typeof()括號(hào)里面的變量,自動(dòng)識(shí)別變量類型并返回該類型肃晚。
typeof 常見(jiàn)運(yùn)用于Block中锚贱,避免循環(huán)引用發(fā)生的問(wèn)題。
用法:

//定義一個(gè)和self相同數(shù)據(jù)類型的bself 关串,并賦值為self拧廊,在block中使用
__weak typeof (self) weakSelf = self;

注意: typeof 括號(hào)中的值和等于后面的值是相同的類型。

__weak typeof(self.contentView) ws = self.contentView;

typedef:定義一種類型的別名悍缠,而不只是簡(jiǎn)單的宏替換卦绣。
typedef 常用于命名(枚舉和Block)
用法1-結(jié)構(gòu)體

//結(jié)構(gòu)體
typedef struct Myrect {
    float width;
    float height;
}myRect;

用法2-枚舉

//枚舉值 它是一個(gè)整形(int)  并且,它不參與內(nèi)存的占用和釋放,枚舉定義變量即可直接使用,不用初始化.
//在代碼中使用枚舉的目的只有一個(gè),那就是增加代碼的可讀性.
typedef NS_ENUM (NSUInteger,direction){
    left=0,
    right=1,
    top =2,
    down =3
};
typedef NS_ENUM (NSUInteger,direction_2){
    left2 = 0,
    right2 = 1 << 0,
    top2 = 1 << 1,
    down2 = 1 << 2
};

用法3-Block

//1.重新起個(gè)名字
typedef void(^PassValueBlock)(NSString *);
@interface BlockViewController : BaseViewController
//2.聲明block屬性
@property(nonatomic,copy)PassValueBlock  passValueBlock;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市飞蚓,隨后出現(xiàn)的幾起案子滤港,更是在濱河造成了極大的恐慌,老刑警劉巖趴拧,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溅漾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡著榴,警方通過(guò)查閱死者的電腦和手機(jī)添履,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)脑又,“玉大人暮胧,你說(shuō)我怎么就攤上這事∥属铮” “怎么了往衷?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)严卖。 經(jīng)常有香客問(wèn)我席舍,道長(zhǎng),這世上最難降的妖魔是什么哮笆? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任来颤,我火速辦了婚禮汰扭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘福铅。我一直安慰自己萝毛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布滑黔。 她就那樣靜靜地躺著珊泳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拷沸。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天薯演,我揣著相機(jī)與錄音撞芍,去河邊找鬼。 笑死跨扮,一個(gè)胖子當(dāng)著我的面吹牛序无,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衡创,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼帝嗡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了璃氢?” 一聲冷哼從身側(cè)響起哟玷,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎一也,沒(méi)想到半個(gè)月后巢寡,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡椰苟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年抑月,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舆蝴。...
    茶點(diǎn)故事閱讀 38,650評(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,936評(píng)論 3 313
  • 文/蒙蒙 一疲陕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钉赁,春花似錦蹄殃、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至带膜,卻和暖如春吩谦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背膝藕。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工式廷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芭挽。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓滑废,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親袜爪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蠕趁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

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