Objective-C 宏定義

1. 判斷設(shè)備

// 是否高清屏  
#define isRetina ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO)  
// 是否模擬器  
#define isSimulator (NSNotFound != [[[UIDevice currentDevice] model] rangeOfString:@"Simulator"].location)  
// 是否iPad  
#define isPad (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)  
// 是否iPad  
#define someThing (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)? ipad: iphone  

2. 基本的使用

//定義π值 3.1415926    
#define PI 3.1415926     
//則在程序用可以如下使用       
double i=2*PI*3;     
//效果相當(dāng)于  double i=2*3.1415926*3;    
  
//預(yù)處理命令可以定義任何符合格式的形式板乙,例如判斷年份是否閏年  
#define  IS_LEAP_YEAR  year%4==0&&year%100!=0||year%400==0    
//使用時(shí)則可以直接    
if(IS_LEAP_YEAR)    
   
//或者可以定義一個(gè)參數(shù)      
#define  IS_LEAP_YEAR(y)  y%4==0&&y%100!=0||y%400==0    
//使用時(shí)則可以直接     
int ys=2012;     
if(IS_LEAP_YEAR(ys))       
    
//通常預(yù)處理程序定義在一行 如果好分行 比如說太長(zhǎng)需要換行  需要使用“/”符號(hào) 表示還有下一行步做,多行分列也是如此耳璧,例:    
#Define  IS_LEAP_YEAR  year%4==0&&year%100!=0/    
           ||year%400==0     
//宏定義參數(shù)后邊放一個(gè)# 那么在調(diào)用該宏時(shí),預(yù)處理程序?qū)⒏鶕?jù)宏參數(shù)創(chuàng)建C風(fēng)格的常量字符串 例:    
#define STR(x) # x    
//將會(huì)使得 隨后調(diào)用的      
  
NSLOG(STR(Programming in Objective-c./n));    
//顯示結(jié)果為 Programming in Objective-c./n  

3. 關(guān)于#與##的操作符

  • 宏定義中字符串操作符#:
    #的功能是將其后面的宏參數(shù)進(jìn)行字符串化操作键袱,意思就是對(duì)它所應(yīng)用的宏變量通過替換后在其左右各加上一個(gè)雙引號(hào)护桦。例如
    #define WARN_IF(EXPR)\  
do {\  
if (EXPR)\  
fprintf(stderr, "Warning: " #EXPR "\n");\  
} while(0)  
  
上面代碼中的反斜線\主要用來(lái)轉(zhuǎn)譯換行符,即屏蔽換行符矾瘾。  
  
那么如下的代碼調(diào)用:  
WARN_IF(divider == 0);  
  
將被解析為:  
do {\  
if (divider == 0)\  
fprintf(stderr, "Warning: " "divider == 0" "\n");\  
} while(0);  
  • 宏定義中的連接符##:
    連接符##用來(lái)將兩個(gè)token連接為一個(gè)token,但它不可以位于第一個(gè)token之前or最后一個(gè)token之后箭启。注意這里連接的對(duì)象只要是token就行壕翩,而不一定是宏參數(shù),但是##又必須位于宏定義中才有效,因其為編譯期概念(比較繞)册烈。
#define LINK_MULTIPLE(a, b, c, d) a##_##b##_##c##_##d  
typedef struct _record_type LINK_MULTIPLE(name, company, position, salary);  
/*  
* 上面的代碼將被替換為  
* typedef struct _record_type name_company_position_salary;  
*/  
  
又如下面的例子:  
#define PARSER(N) printf("token" #N " = %d\n", token##N)  
  
int token64 = 64;  
  
如下調(diào)用宏:  
PARSER(64);  
  
將被解析為:  
printf("token" "64" " = %d\n", token64);  
  
在obj-c中戈泼,如果我有如下定義:  
#define _X(A, B) (A#B)  
#define _XX(A, B) _X([NSString stringWithFormat:@"%@_c", A], B)  
gcc將報(bào)錯(cuò)婿禽!  
正確的寫法為:  
#define _XX(A, B) _X(([NSString stringWithFormat:@"%@_c", A]), B)  

4. 宏定義 Objective-C 單例

#define GTMOBJECT_SINGLETON_BOILERPLATE(_object_name_, _shared_obj_name_)  
static _object_name_ *z##_shared_obj_name_ = nil;   
+ (_object_name_ *)_shared_obj_name_ {              
@synchronized(self) {                             
if (z##_shared_obj_name_ == nil) {              
/* Note that ‘self’ may not be the same as _object_name_ */                                
/* first assignment done in allocWithZone but we must reassign in case init fails */       
z##_shared_obj_name_ = [[self alloc] init];                                                
_GTMDevAssert((z##_shared_obj_name_ != nil), @”didn’t catch singleton allocation”);        
}                                               
}                                                 
return z##_shared_obj_name_;                      
}                                                   
  
+ (id)allocWithZone:(NSZone *)zone {                
@synchronized(self) {                             
if (z##_shared_obj_name_ == nil) {              
z##_shared_obj_name_ = [super allocWithZone:zone];  
return z##_shared_obj_name_;                  
}                                               
}                                                 
   
/* We can’t return the shared instance, because it’s been init’d */  
_GTMDevAssert(NO, @”use the singleton API, not alloc+init”);         
return nil;                                       
}                                                   
  
- (id)retain {                                      
return self;                                      
}                                                   
  
- (NSUInteger)retainCount {                         
return NSUIntegerMax;                             
}                                                   
  
- (void)release {                                   
}                                                   
  
- (id)autorelease {                                 
return self;                                      
}                                                   
  
- (id)copyWithZone:(NSZone *)zone {                 
return self;                                      
}
    ```

### 5. 條件編譯
```ObjC
#if !defined(FCDebug) || FCDebug == 0  
#define FCLOG(...) do {} while (0)  
#define FCLOGINFO(...) do {} while (0)  
#define FCLOGERROR(...) do {} while (0)  
     
#elif FCDebug == 1  
#define FCLOG(...) NSLog(__VA_ARGS__)  
#define FCLOGERROR(...) NSLog(__VA_ARGS__)  
#define FCLOGINFO(...) do {} while (0)  
     
#elif FCDebug > 1  
#define FCLOG(...) NSLog(__VA_ARGS__)  
#define FCLOGERROR(...) NSLog(__VA_ARGS__)  
#define FCLOGINFO(...) NSLog(__VA_ARGS__)  
#endif  
    ```

### 6. 參照C語(yǔ)言的預(yù)處理命令簡(jiǎn)介:

define 定義一個(gè)預(yù)處理宏

undef 取消宏的定義

include 包含文件命令

include_next 與#include相似, 但它有著特殊的用途

if 編譯預(yù)處理中的條件命令, 相當(dāng)于C語(yǔ)法中的if語(yǔ)句

ifdef 判斷某個(gè)宏是否被定義, 若已定義, 執(zhí)行隨后的語(yǔ)句

ifndef 與#ifdef相反, 判斷某個(gè)宏是否未被定義

elif 若#if, #ifdef, #ifndef或前面的#elif條件不滿足, 則執(zhí)行#elif之后的語(yǔ)句, 相當(dāng)于C語(yǔ)法中的else-if

else 與#if, #ifdef, #ifndef對(duì)應(yīng), 若這些條件不滿足, 則執(zhí)行#else之后的語(yǔ)句, 相當(dāng)于C語(yǔ)法中的else

endif #if, #ifdef, #ifndef這些條件命令的結(jié)束標(biāo)志.

defined 與#if, #elif配合使用, 判斷某個(gè)宏是否被定義

line 標(biāo)志該語(yǔ)句所在的行號(hào)

將宏參數(shù)替代為以參數(shù)值為內(nèi)容的字符竄常量

將兩個(gè)相鄰的標(biāo)記(token)連接為一個(gè)單獨(dú)的標(biāo)記

pragma 說明編譯器信息#warning 顯示編譯警告信息

error 顯示編譯錯(cuò)誤信息

參考鏈接:http://www.uml.org.cn/c++/200902104.asp
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市大猛,隨后出現(xiàn)的幾起案子扭倾,更是在濱河造成了極大的恐慌,老刑警劉巖挽绩,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膛壹,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡唉堪,警方通過查閱死者的電腦和手機(jī)模聋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)唠亚,“玉大人链方,你說我怎么就攤上這事≡钏眩” “怎么了祟蚀?”我有些...
    開封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)割卖。 經(jīng)常有香客問我前酿,道長(zhǎng),這世上最難降的妖魔是什么鹏溯? 我笑而不...
    開封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任罢维,我火速辦了婚禮,結(jié)果婚禮上丙挽,老公的妹妹穿的比我還像新娘肺孵。我一直安慰自己,他們只是感情好颜阐,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開白布悬槽。 她就那樣靜靜地躺著,像睡著了一般瞬浓。 火紅的嫁衣襯著肌膚如雪初婆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天猿棉,我揣著相機(jī)與錄音磅叛,去河邊找鬼。 笑死萨赁,一個(gè)胖子當(dāng)著我的面吹牛弊琴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播杖爽,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼敲董,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼紫皇!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起腋寨,我...
    開封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤聪铺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后萄窜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铃剔,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年查刻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了键兜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡穗泵,死狀恐怖普气,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情佃延,我是刑警寧澤棋电,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站苇侵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏企锌。R本人自食惡果不足惜榆浓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望撕攒。 院中可真熱鬧陡鹃,春花似錦、人聲如沸抖坪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)擦俐。三九已至脊阴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蚯瞧,已是汗流浹背嘿期。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留埋合,地道東北人备徐。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像甚颂,于是被迫代替她去往敵國(guó)和親蜜猾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秀菱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

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