RAC 宏学习

1.动态参数个数的计算

metamacro_argcount(...)

这个宏是用来计算参数个数的,其实就是根据__VA_ARGS__可变原则,以及参数占位原则来实现的

#define diy_argcount(...)

定义了上面这个宏,里面的...就是__VA_ARGS__,如果写成

diy_argcount(1,2,3)

那么__VA_ARGS__就是1,2,3,稍微变化一下

#define diy_argcount_1(parm1,...)
#define diy_argcount(...) diy_argcount_1(__VA_ARGS__)

此时上面的diy_argcount_1__VA_ARGS__就变成2,3, parm1就变成了1,再来看看metamacro_argcount

#define metamacro_argcount(...) \
        metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

#define metamacro_at(N, ...) \
        metamacro_concat(metamacro_at, N)(__VA_ARGS__)

假设我们代码是metamacro_argcount(obj1,obj2,obj3)那么根据上面的宏变换下,就是

metamacro_at20(obj1,obj2,obj3,20,19,....2,1)

#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, 
_7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) 
metamacro_head(__VA_ARGS__)

metamacro_at20(obj1,obj2,obj3,20,19,....2,1)中前面的20个参数逐个应对_1,_2,_3...._20这样的变量,也及时相当于

_0  = obj1,
_1  = obj2,
_2  = obj3,
_3 = 20,
_4 = 19
.
.
.
_19 = 4

这样metamacro_head(__VA_ARGS__)中的__VA_ARGS__就是3,2,1
metamacro_head定义如下

#define metamacro_head_(FIRST, ...) FIRST

那么metamacro_head_ (3,2,1)就是3也就是有三个参数的输入

2.@weakify(obj1,obj2,obj3)实现

如果weakify只可以接受一个参数,这样的宏都会写

#define weakify(_1)   __weak __typeof__(_1)  _1##_weak_ = (_1)

我们可以通过动态获取参数个数的方法,拿到obj1, obj2, obj3,再对他们每个rac_weakify_
简化下RAC以后的宏定义

#define rac_weakify_(VAR) \
    __weak __typeof__(VAR)   VAR##_weak_ = (VAR);

定义

#define rac_weakify_20(N,SEP,...)  rac_weakify_(N)\
SEP\
rac_weakify_19(__VA_ARGS__)

#define rac_weakify_19(N,SEP,...)  rac_weakify_(N)\
SEP\
rac_weakify_18(__VA_ARGS__)
.
.
.
#define rac_weakify_1(N)  rac_weakify_(N)

那么weakify宏就可以写成

#define weakify(...)  (rac_weakify_##metamacro_argcount(__VA_ARGS__))(__VA_ARGS__)

而RAC为了区分在这类的宏在前面加个@,其实就是

#define weakify(...)  autoreleasePool{}  (rac_weakify_##metamacro_argcount(__VA_ARGS__))(__VA_ARGS__)

其中SEP就是宏定义空字符,用来分开宏定义字符连接

关键点

假设定义#define macro1 左(...) 右(__VA_ARGS__)
关键点:宏中的...=> __VA_ARGS__从左到右是全映射
而宏中右部分的__VA_ARGS__映射到另一个宏时,是逐个映射到变量,只有映射不到的时候,或者有剩余没有映射到的参数才映射到...

你可能感兴趣的:(RAC 宏学习)