美文网首页
RAC 宏学习

RAC 宏学习

作者: AryCode | 来源:发表于2019-10-21 15:22 被阅读0次

    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 宏学习

          本文链接:https://www.haomeiwen.com/subject/tmftvctx.html