项目中用到了@weakify的宏定义, 正好今天任务解决了, 就一步一步拆分下看看它是怎么实现的.
下面就一步一步拆分@weakify
object-c
@weakify(self) 中@weakify的宏定义如下
#define weakify(...) \
ext_keywordify \
metamacro_foreach_cxt(ext_weakify_,, __weak, __VA_ARGS__)
/* @weakify(self)
可以替换为
ext_keywordify \
metamacro_foreach_cxt(ext_weakify_,, __weak, self)
*/
分段拆解
- 先看
ext_keywordify
, 替换为autoreleasepool {}
; 知道为什么weakify前面为什么要加@了吧, 是在这里用的.
效果:
@autoreleasepool {}
metamacro_foreach_cxt(ext_weakify_,, __weak, self)
- 在看
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(VA_ARGS)
这个宏的作用是返回一共参数有多少个
工作原理是截取前二十个
#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_at20(__VA_ARGS__), 并且参数最后20位为20到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_head(__VA_ARGS__) //宏的作用是取第一个参数
再这样的话, 前20个参数一一对应, 最后会剩下1(以@weakify(self)为例);
效果:
metamacro_foreach_cxt1(ext_weakify_,, __weak, self)
//按照#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
进一步转化为
ext_weakify_(0, _weak, self);
再带入ext_weakify
转化为:
__weak __typeof__(self) self_weak_ = (self);
分解完毕
@strongify要在block中使用
@strongify想要看的自己完成, 最终结果为
__strong __typeof__(self) self = self_weak_;
想要具体过程的, 推荐简书文章WzxJiang的剖析@weakify、@strongify
感谢WzxJiang在简书上的文章, 对我帮助很大, 对宏的了解又增加了许多