SDWebImage扩展笔记(二)

2019-04-10  本文已影响0人  null_2562

@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大神的说明
英语好的同学通道
汉语通道

上一篇下一篇

猜你喜欢

热点阅读