SDWebImage扩展笔记(二)
@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)
替换
MACRO
为 sd_weakify_
CONTEXT
为 __weak
_0
为 self
替换结果
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
大神的说明
英语好的同学通道
汉语通道