#if#ifdef#define等宏定義使用

吐槽:為了提前適配iOS 11,在xcode9 beta版使用過程中,有時候xcode9 beta看圖層一點擊就卡死啊,還得強退才行;playground全局搜索代碼有時候失效啊;打包啊....??都得換回xcode8才行。。。
最近碰到了個代碼執行問題,iOS 11中一些新的API在xdode8中報錯,每次切換xcode時,都得去注釋掉這段代碼,麻煩死了。怎么讓一段代碼在xcode8和9都能順利編譯不報錯,可用宏做如下設置:

#import "UIScrollView+SFScrollView.h”

@implementation UIScrollView (SFScrollView)

- (void)neverAdjustmentContentInset{
#ifdef __IPHONE_11_0
    if (@available(iOS 11.0, *) ) {
        self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
#endif
}

@end
//> scrollview的分類中添加的方法,是iOS 11才有的。而宏__IPHONE_11_0,也是iOS 11才有的,故用#ifdef __IPHONE_11_0即可完美解決,
整理一下,方便使用:

預處理就是在進行編譯的第一遍詞法掃描和語法分析之前所作的工作。說白了,就是對源文件進行編譯前,先對預處理部分進行處理,然后對處理后的代碼進行編譯。這樣做的好處是,經過處理后的代碼,將會變的很精短。

#define  定義一個預處理宏
#undef   取消宏的定義
#if      編譯預處理中的條件命令, 相當于C語法中的if語句
#ifdef   判斷某個宏是否被定義(#define過), 若已定義, 執行隨后的語句
#ifndef  與#ifdef相反, 判斷某個宏是否未被定義
#elif    若#if, #ifdef, #ifndef或前面的#elif條件不滿足, 則執行#elif之后的語句, 相當于C語法中的else-if
#else    與#if, #ifdef, #ifndef對應, 若這些條件不滿足, 則執行#else之后的語句, 相當于C語法中的else
#endif   #if, #ifdef, #ifndef這些條件命令的結束標志.
defined   與#if, #elif配合使用, 判斷某個宏是否被定義
#pragma  說明編譯器信息
#warning 顯示編譯警告信息
#error   顯示編譯錯誤信息
配置DEBUG宏:
1.在 "Target > Build Settings > Preprocessor Macros > Debug" 設置"DEBUG=1”。

2.之后在pch或工具類中就可以這么寫了:
#ifdef DEBUG  
(debug 模式下的配置)
#else  
(release 模式下的配置)
#endif 

#ifdef DEBUG // 調試狀態, 打開LOG功能

#define SFString [NSString stringWithFormat:@"%s", __FILE__].lastPathComponent
//打印出所在文件名,所在行,堆棧地址
#define SFLog(...) printf("%s: %p (line = %d): %s\n\n", [SFString UTF8String] , &self, __LINE__, [[NSString stringWithFormat:__VA_ARGS__] UTF8String]);

//#else
//#define SFLog(s, ...) NSLog(@"<%@: %p (line = %d)> %@", self.class, self, __LINE__,[NSString stringWithFormat:(s),##__VA_ARGS__])
//#endif

#else // 發布狀態, 關閉LOG功能
#define SFLog(s, ...)
#endif

系統宏介紹:

 __LINE__:宏在預編譯時會替換成當前的行號

 __FUNCTION__:宏在預編譯時會替換成當前的函數名稱

__VA_ARGS__:簡單的說,就是將左邊…的內容替換進來
詳解#ifdef,#elif,#else,#endif,#if等:
1:
  #ifdef _XXXX  (ifdef 即 if define )
  ...程序段1...
   #elif defined _YYYY
   ...程序段3...(相當于else if)
  #else
  ...程序段2...
  #endif
   
>這表明如果_XXXX已被#define定義過,則對程序段1進行編譯;再如果定義了_YYYY,執行程序段3,否則對程序段2進行編譯。

  例: 
  #define NUM
  .............

  #ifdef NUM
   printf("之前NUM有過定義啦!:) \n");
  #else
   printf("之前NUM沒有過定義!:( \n");
  #endif

>如果程序開頭有#define NUM這行,即NUM有定義,碰到下面#ifdef NUM的時候,當然執行第一個printf。否則第二個printf將被執行。
   我認為,用這種,可以很方便的開啟/關閉整個程序的某項特定功能。
2: 
  #ifndef _XXXX 
  ...程序段1... 
  #else 
  ...程序段2... 
  #endif

>這里使用了#ifndef,表示的是if not def。和#ifdef相反的狀況(如果沒有定義了標識符_XXXX,那么執行程序段1,否則執行程序段2)
3:
  #if 常量 
  ...程序段1...
  #else
  ...程序段2...
  #endif 
  
 >注意:#if后必須跟常量,不能是宏(因為宏是在運行階段才有,#if是預編譯階段,找不到宏);
  如果常量為真(非0,隨便什么數字,只要不是0),就執行程序段1,否則執行程序段2。
 我認為,這種方法可以將測試代碼加進來。當需要開啟測試的時候,只要將常量變1就好了。而不要測試的時候,只要將常量變0。
常用示例:

1.判斷當前app所支持的最大最小iOS版本

#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED // 當前軟件支持的最大ios版本
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000  
      NSLog(@"當前app支持的最大版本,%d",__IPHONE_OS_VERSION_MAX_ALLOWED);
#else
      NSLog(@"當前app支持的最大版本,%d",__IPHONE_OS_VERSION_MAX_ALLOWED);
#endif
#endif

#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED // 當前軟件支持的最小ios版本
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80400
      NSLog(@"當前app支持的最小版本,%d",__IPHONE_OS_VERSION_MIN_REQUIRED);
#else
     NSLog(@"當前app支持的最小版本,%d",__IPHONE_OS_VERSION_MIN_REQUIRED);
#endif
#endif

2.判斷真機/模擬器

#if TARGET_OS_IOS
    NSLog(@"真機測試");
#endif

#if TARGET_IPHONE_SIMULATOR
    NSLog(@"模擬器");
#endif

3.獲得當前設備的iOS版本

#define kIOSVersion  [[UIDevice currentDevice].systemVersion doubleValue]

4.字體(帶參數的宏)

#define SFSystemFont(FONTSIZE) [UIFont systemFontOfSize:FONTSIZE]

5.weak strong (RAC寫法)

// weak self
#ifndef weakify
#if DEBUG
#if __has_feature(objc_arc)
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
#endif
#else
#if __has_feature(objc_arc)
#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
#endif
#endif
#endif

// strong self
#ifndef strongify
#if DEBUG
#if __has_feature(objc_arc)
#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
#endif
#else
#if __has_feature(objc_arc)
#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
#endif
#endif
#endif

6.去警告

#define SuppressPerformSelectorLeakWarning(Stuff) \
do { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \
Stuff; \
_Pragma("clang diagnostic pop") \
} while (0)

7.GCD Block

#define GCDBlock(block) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block)
#define GCDMainBlock(block) dispatch_async(dispatch_get_main_queue(),block)
#define CGDMainBack GCDMainBlock(^(){})

8......很多很多.........

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容

  • 因為要結局swift3.0中引用snapKit的問題,看到一篇介紹Xcode8,swift3變化的文章,覺得很詳細...
    uniapp閱讀 4,464評論 0 12
  • “媽媽,我想對你說,話到嘴邊又咽下”。每次聽到《燭光里的媽媽》,我都會想到自己的母親。對她老人家我也有欲言又止的時...
    海燕_f75a閱讀 318評論 9 9
  • 女兒去美國留學學影視編導,考慮到專業需要,以便對色彩有更好的把握,她選修了油畫,每周學習一個下午。油畫選修班的學生...
    一念清寧閱讀 621評論 11 17
  • 這兩天研究了太多東西,更多的是人性,在對的時間做對的事情,人性使然……突然想到前幾年做的一個...
    小舟如畫閱讀 614評論 3 1
  • 《逃逸》(完結) 文/海小俠 圖/海小俠 人 從出生開始就選擇了逃逸 他選擇了裝聾作啞 他選擇了懵懂無知 他逃過了...
    明海小俠閱讀 216評論 0 0