#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阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • 因为要结局swift3.0中引用snapKit的问题,看到一篇介绍Xcode8,swift3变化的文章,觉得很详细...
    uniapp阅读 4,290评论 0 12
  • “妈妈,我想对你说,话到嘴边又咽下”。每次听到《烛光里的妈妈》,我都会想到自己的母亲。对她老人家我也有欲言又止的时...
    海燕_f75a阅读 299评论 9 9
  • 女儿去美国留学学影视编导,考虑到专业需要,以便对色彩有更好的把握,她选修了油画,每周学习一个下午。油画选修班的学生...
    会宁土豆阅读 559评论 11 17
  • 这两天研究了太多东西,更多的是人性,在对的时间做对的事情,人性使然……突然想到前几年做的一个...
    小舟如画阅读 590评论 3 1
  • 《逃逸》(完结) 文/海小侠 图/海小侠 人 从出生开始就选择了逃逸 他选择了装聋作哑 他选择了懵懂无知 他逃过了...
    明海小侠阅读 183评论 0 0