@weakify和@strongify实现分析
2016-05-04 本文已影响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变量。