iOS ——宏#define、const(static、extern)、枚舉enum

一、宏

宏的常見用法:
1、常見字符串抽成宏
2、常見代碼抽成宏

#define DEFINE @"Hello"
#define WIDTH 10.0
#define ZYXUserInstance [ZYXUser shareInstance]

二、const 常量

翻譯 const :常數(shù),不變的。
const是一個關(guān)鍵字。它限定一個變量不允許被改變,產(chǎn)生靜態(tài)作用。使用const在一定程度上可以提高程序的安全性和可靠性。
const修飾的數(shù)據(jù)類型是指常類型,常類型的變量或?qū)ο蟮闹凳遣荒鼙桓碌摹?br> const 推出的初始目的,正是為了取代預(yù)編譯指令,消除它的缺點,同時繼承它的優(yōu)點

三、const與宏的區(qū)別

1.1 宏在預(yù)編譯時處理(宏在編譯開始之前就會被替換)
const會在編譯時被處理
1.2 define宏沒有類型,宏不做任何類型檢查,不會報編譯錯誤,只是替換
const常量有具體的類型,會編譯檢查,會報編譯錯誤
1.3 宏的好處:宏能定義一些函數(shù),方法。
const不能;使用大量宏,容易造成編譯時間久,每次都需要重新替換
1.4 宏僅僅是展開,有多少地方使用,就展開多少次,不會分配內(nèi)存。(宏定義不分配內(nèi)存,變量定義分配內(nèi)存。)
 const常量會在內(nèi)存中分配(可以是堆中也可以是棧中)。
1.5 const 可以節(jié)省空間,避免不必要的內(nèi)存分配

const
#define PI 3.14159 //常量宏 const doulbe Pi=3.14159; //此時并未將Pi放入ROM中
double I=PI; //預(yù)編譯期間進行宏替換,分配內(nèi)存 double i=Pi; //此時為Pi分配內(nèi)存,以后不再分配!
double J=PI; //再進行宏替換,又一次分配內(nèi)存 double j=Pi; //沒有內(nèi)存分配

const定義常量從匯編的角度來看,只是給出了對應(yīng)的內(nèi)存地址,而不是象#define一樣給出的是立即數(shù),所以,const定義的常量在程序運行過程中只有一份拷貝(因為是全局的只讀變量,存在靜態(tài)區(qū)),而 #define定義的常量在內(nèi)存中有若干個拷貝。
1.6 提高了效率。 編譯器通常不為普通const常量分配存儲空間,而是將它們保存在符號表中,這使得它成為一個編譯期間的常量,沒有了存儲與讀內(nèi)存的操作,使得它的效率也很高。

2.1 const僅僅用來修飾右邊的變量
2.2 被const修飾的變量是只讀的
2.3 const簡單使用

//全局變量,constString1地址不能修改,constString1值能修改
const NSString *constString1 = @"I am a const NSString * string";
//意義同上,無區(qū)別
NSString const *constString2 = @"I am a NSString const * string";
// stringConst 地址能修改,stringConst值不能修改
NSString * const stringConst = @"I am a NSString * const string";

constString1 跟constString2 無區(qū)別.
*左邊代表指針本身的類型信息,const表示這個指針指向的這個地址是不可變的
*右邊代表指針指向變量的可變性,即指針存儲的地址指向的內(nèi)存單元所存儲的變量的可變性

四、const與static和extern配合使用

1.static的作用 ——局部變量(只在文件內(nèi)部使用)
1.1 延長局部變量的生命周期,程序結(jié)束才會銷毀
1.2 局部變量只會生成一份內(nèi)存,只會初始化一次
1.3 改變局部變量的作用域
1.4 只能在本文件中訪問,修改全局變量的作用域,生命周期不會改
1.5 避免重復(fù)定義全局變量

static NSString * const kConst = @"Hello";
static const CGFloat kWidth = 10.0;

2.extern的作用——全局變量(對外公開)
2.1 只是用來獲取全局變量(包括全局靜態(tài)變量)的值,不能用于定義變量
2.2 先在當前文件查找有沒有全局變量,沒有找到,才會去其他文件查找
extern常用在.h聲明中
//Test.h
extern NSString * const CLASSNAMEconst;
//Test.m
NSString * const CLASSNAMEconst = @"hello";

五、enum枚舉類型

枚舉常量不會占用對象的存儲空間,它們在編譯時被全部求值。枚舉常量的缺點是:它的隱含數(shù)據(jù)類型是整數(shù),其最大值有限,且不能表示浮點數(shù)(如PI=3.14159)。
typedef enum {
Third_None = -1,
Third_WEIXIN,
Third_QQ,Third_WEIBO
} ThirdType;

在iOS6和Mac OS 10.8以后Apple引入了兩個宏來重新定義這兩個枚舉類型,實際上是將enum定義和typedef合二為一,并且采用不同的宏來從代碼角度來區(qū)分。

NS_OPTIONS一般用來定義位移相關(guān)操作的枚舉值,我們可以參考UIKit.Framework的頭文件,可以看到大量的枚舉定義。

typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {  
    UIViewAnimationTransitionNone,//默認從0開始  
    UIViewAnimationTransitionFlipFromLeft,  
    UIViewAnimationTransitionFlipFromRight,  
    UIViewAnimationTransitionCurlUp,  
    UIViewAnimationTransitionCurlDown,  
};  

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {  
    UIViewAutoresizingNone                 = 0,  
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,  
    UIViewAutoresizingFlexibleWidth        = 1 << 1,  
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,  
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,  
    UIViewAutoresizingFlexibleHeight       = 1 << 4,  
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5  
};  

從枚舉定義來看,NS_ENUM和NS_OPTIONS本質(zhì)是一樣的,僅僅從字面上來區(qū)分其用途。NS_ENUM是通用情況,NS_OPTIONS一般用來定義具有位移操作或特點的情況(bitmask)。

位移枚舉詳解

枚舉的定義還支持位運算的方式定義,就是NS_OPTIONS

特點1:等于號后面必須等于1
特點2:按照2進制位移位數(shù),確定數(shù)值

typedef NS_ENUM(NSInteger, Test)  
{  
  TestA       = 1,      //1   1   1  
  TestB       = 1 << 1, //2   2   10 
  TestC       = 1 << 2, //4   3   100  
  TestD       = 1 << 3, //8   4   1000   
  TestE       = 1 << 4  //16  5   10000  

};

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容