@weakify和@strongify实现分析

作者: 熊妹妹 | 来源:发表于2016-05-04 11:39 被阅读817次

    在RAC里用@weakify和@strongify对block内使用self进行管理,这两个宏来自libextobjc扩展库。

    @weakify(self)
    

    打开第一层

    @autoreleasepool {} metamacro_foreach_cxt(ext_weakify_,, __weak, __VA_ARGS__)
    

    把参数替换一下

    @autoreleasepool {} metamacro_foreach_cxt(ext_weakify_,, __weak, self)
    

    看一下metamacro_foreach_cxt的实现

    #define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
        metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
    

    这里有一个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)
    

    VA_ARGS表示的是宏定义中的...中的所有剩余参数,替换参数如下。

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

    展开metamacro_at,参数N就是20,metamacro_concat实现了拼接功能

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

    以上展开替换后变成

    metamacro_at20(self, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
    

    展开metamacro_at20方法

    #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__)
    

    也就是截断前20个参数,变成

    metamacro_head(1)
    

    再打开

    #define metamacro_head(...) \
        metamacro_head_(__VA_ARGS__, 0)
        
    #define metamacro_head_(FIRST, ...) FIRST
    

    所以metamacro_argcount(VA_ARGS)的运行结果就是1

    @weakify就可以写成

    @autoreleasepool {} metamacro_foreach_cxt1(ext_weakify_, SEP, __weak, self)
    

    打开metamacro_foreach_cxt1和ext_weakify_实现

    #define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
    
    #define ext_weakify_(INDEX, CONTEXT, VAR) \
    CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
    

    替换metamacro_foreach_cxt1和ext_weakify_就变成

    @autoreleasepool {} CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
    

    将参数 CONTEXT=_weak,VAR=self 进行替换

    @autoreleasepool{}  __weak __typeof__(self) self_weak_ = (self);
    

    也就是说@weakify(self)声明了一个指向self的弱引用类型的变量self_weak_。

    同理可以分析出@strongify(self)是声明一个_strong类型的指向self_weak的self变量。

    相关文章

      本文标题:@weakify和@strongify实现分析

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