iOS--宏定义

预处理

C语言的预处理(预编译)主要有三个方面的内容: 1.宏定义; 2.文件包含; 3.条件编译。“#”是编译器预处理的标志。

预处理(预编译)工作也叫做宏展开:将宏名替换为文本(这个文本可以是字符串、可以是代码等)。
掌握"宏"概念的关键是“换”。

1.宏定义:预处理阶段会将程序中所有用到宏定义的地方替换成原内容。因此,使用宏定义可以减少代码量,保持一致性,使开发过程更轻松。

2.文件包含:指的是头文件的引入,在预编译阶段会把引入头文件的内容拷贝至当前文件中。

#import "ClassA.h"

#import

3.条件编译:预编译时可以根据条件来决定编译哪块代码,可以减少编译的代码量

条件编译指令 释义
#undef 取消已定义的宏
#if 判断表达式真假
#ifdef 如果宏已经定义
#ifndef 如果宏没有定义
#elif 上边表达式不成立时,判断当前表达式是否成立
#endif 结束一个#if……#else条件编译块

宏定义

上边简单的提了一下宏定义,这里重点记录下宏定义一些语法和用法。

  1. 无参宏(直接带过)

#define NUMBER 100
#define NOTIFICATION_CENTER [NSNotificationCenter defaultCenter]

  1. 带参宏
  • 固定参数
    如果让你实现一个取最小值的宏函数,你一定觉的很简单,然后胸有成竹的就写出了这行代码

#define MIN(A,B) A < B ? A : B

看着逻辑上也没有什么毛病,嚯嚯嚯,小伙子,入坑了吧!我们知道预处理会在预编译阶段将预定义标识替换成原内容,如果有宏嵌套,宏展开后,原先的逻辑可能会因为运算符的优先级导致输出错误。具体详解请看大神之作《宏定义的黑魔法 - 宏菜鸟起飞手册》。

正确写法:(这真的不是一般的麻烦啊。。。)

#define MIN(A,B) ({ __typeof__(A)__a = (A); __typeof__(B) __b = (B); __a < __b ? __a :__b; })

  • 可变参数及特殊语法
特殊标识 释义 示例
# 单个”#“号的作用是字符串化 #define A(x) #x 调用 A(123) 将得到c字符串 "123"
@ @是objc的编译符号,不属于宏操作的对象 #define A(x) @#x 将得到OC字符串 @"123"
\ 连接换行符 放在行尾 然后换行 用来连接代码块
## 双井号是连接符 #define A(x,y) x##y 调用 A(123,456) ==> 123456
__ 双下滑线表示预定义,即已经定义过的 __TIME__, __FUNCTION__, __LINE__ 等
... 任意个数的参数,但是宏定义中只有... ,那么起码有1个参数 #define NSLog(...) {(NSLog)((format),__VAR_VACHS__);}
__VA_ARHS__ 配合...使用,表示的是宏定义中的...中的所有剩余参数,至少一个 同上
##__VA_ARHS__ 参数个数不限制,可为0 #define NSLog(format, ...) {(NSLog)((format),##__VAR_VACHS__);}

宏定义示例

单例
#define RF_SINGLETION(__clazz) \
+ (__clazz *)sharedInstance;

#define RF_DEF_SINGLETION(__clazz) \
static __clazz * __singletion;\
+ (__clazz *)sharedInstance \
{\
static dispatch_once_t once; \
dispatch_once(&once,^{__singletion = [[__clazz alloc] init];});\
return __singletion;\
}\
+ (id)allocWithZone:(struct _NSZone *)zone {\
    \
    if (!__singletion) {\
        \
        return [super allocWithZone: zone];\
        \
    }\
    \
    return nil;\
    \
}\
\
- (id)copy {\
    \
    return __singletion;\
    \
}\
初始化方法
#define INIT_CELL(_CLASS_NAME) \
\
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier \
{ \
NSLog(@"-------------- %@ init ----------", self.class); \
    [_CLASS_NAME description]; \
    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { \
        [self _CLASS_NAME##_internalInit]; \
    } \
    \
    return self; \
} \
\
- (void)awakeFromNib \
{ \
    [super awakeFromNib]; \
    \
    [self _CLASS_NAME##_internalInit]; \
} \
\
- (void)_CLASS_NAME##_internalInit

结语

本篇为知识总结,帮助自己查阅资料,后续会不断更新。。。祝大家学习愉快!^_^

你可能感兴趣的:(iOS--宏定义)