美文网首页
SDWebImage扩展笔记(二)

SDWebImage扩展笔记(二)

作者: null_2562 | 来源:发表于2019-04-10 18:12 被阅读0次

    @weakify(...) 和 @strongify(...)

    我们用@weakify(self)来梳理一遍宏的替换流程

    关于数数的宏metamacro_argcount,看不懂的同学请看这里weixin_34255793-小记:那个宏metamacro_argcount

    看完引用文章关于连接宏##和 数数宏metamacro_argcount之后,我们来梳理下weakify的替换过程,

    #ifndef weakify
    #define weakify(...) \
    sd_keywordify \
    metamacro_foreach_cxt(sd_weakify_,, __weak, __VA_ARGS__)
    #endif
    

    先是一个宏sd_keywordify ,下面是替换结果,主要作用是添加'高大上'的@符号

    #if DEBUG
    #define sd_keywordify autoreleasepool {}
    #else
    #define sd_keywordify try {} @catch (...) {}
    #endif
    

    首先看宏metamacro_foreach_cxt接收的4个参数

    sd_weakify_ 为了调用宏时加@符号

    __weak 修饰符
    __VA_ARGS__ 接收可变参数 ... 现传入参数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_concat 链接宏,metamacro_argcount数数宏
    传入参数只有一个self
    所以
    metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
    转义后
    metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, __VA_ARGS__)
    发现metamacro_foreach_cxt1居然也是一个宏

    #define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
    

    替换
    MACROsd_weakify_
    CONTEXT__weak
    _0self
    替换结果

    sd_weakify_(0, __weak, self)
    

    有一个宏sd_weakify_

    #define sd_weakify_(INDEX, CONTEXT, VAR) \
    CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
    

    替换完成

    __weak __typeof__(self) self_weak_ = self;
    
    到此已经替换结束, 我们看@weakify(self)的转义

    连上宏sd_keywordify
    在DEBUG模式下最终结果是

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

    其他模式下

    @try {} @catch (...) {} __weak __typeof__(self) self_weak_ = self;
    

    @strongify(self)和@weakify(self)差不多

    亮宏
    #ifndef strongify
    #define strongify(...) \
    sd_keywordify \
    _Pragma("clang diagnostic push") \
    _Pragma("clang diagnostic ignored \"-Wshadow\"") \
    metamacro_foreach(sd_strongify_,, __VA_ARGS__) \
    _Pragma("clang diagnostic pop")
    #endif
    

    关于_Pragma("clang diagnostic push")请看mattt大神的说明
    英语好的同学通道
    汉语通道

    上文没出现过的宏

    #define sd_strongify_(INDEX, VAR) \
    __strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_);
    
    #define metamacro_foreach(MACRO, SEP, ...) \
            metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__)
    
    #define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
            metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
    
    #define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG)
    

    替换结果是,详细过程诸位同学请演算下,孰能生巧嘛

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

    最后上图,震惊,一名小伙浪费150根头发翻译出来的宏,竟然被xcode这样...

    查看预编译文件选项 源文件和预编译文件对比

    预编译文件把__weak 替换成 __attribute__((objc_ownership(weak)))

    __strong 替换成 __attribute__((objc_ownership(strong)))

    关于__attribute__((objc_ownership(strong)))请看mattt大神的说明
    英语好的同学通道
    汉语通道

    相关文章

      网友评论

          本文标题:SDWebImage扩展笔记(二)

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