在使用RAC的代碼中看到@weakify和@strongify的使用疾党,第一感覺(jué)應(yīng)該是 __weak和__strong的使用,于是就看了一下口叙,關(guān)于這兩者的定義:
@weakify:
#define weakify(...) \
rac_keywordify \
metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
在@weakify的定義的注釋中是這么寫的:Creates \c __weak shadow variables for each of the variables provided as ?arguments, which can later be made strong again with #strongify.
創(chuàng)建一個(gè)weak的變量引用作為參數(shù)提供給每一個(gè)需要調(diào)用的地方担孔,之后能夠再一次變成strong 通過(guò)strongify的方式替蛉。
那接下來(lái)就看一下weakify 的定義:
metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
其中的(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)這部分是參數(shù),我們之后再來(lái)看冠胯,先看metamacro_concat 這個(gè)的定義:
metamacro_concat:
#define metamacro_concat(A, B) \
metamacro_concat_(A, B)
接下來(lái)是metamacro_concat_ 這個(gè)函數(shù)的定義:
metamacro_concat_:
#define metamacro_concat_(A, B) A ## B
這個(gè)函數(shù)首先要認(rèn)清運(yùn)算符 “##” 火诸,這里是連字符的意思,就是A ## B == AB
那么倒推到上面的的宏定義就變成:
#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
(metamacro_foreach_cxt ## metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)?
接下來(lái)就需要先看這個(gè)metamacro_argcount:荠察,之后后面需要連接的參數(shù)是什么置蜀。
metamacro_argcount:返回參數(shù)的個(gè)數(shù)
* Returns the number of arguments (up to twenty) provided to the macro. At least one argument must be provided.
#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)
通過(guò)函數(shù)的注釋可以看出:這個(gè)函數(shù)返回的是參數(shù)的個(gè)數(shù)奈搜,為了驗(yàn)證那么需要繼續(xù)看定義這個(gè)宏的其它的宏metamacro_at的定義:
/**
* Returns the Nth variadic argument (starting from zero). At least
* N + 1 variadic arguments must be given. N must be between zero and twenty,
* inclusive.
*/
#define metamacro_at(N, ...) \
metamacro_concat(metamacro_at, N)(__VA_ARGS__)
通過(guò)宏的注釋可以得到:返回N個(gè)可辨的參數(shù),至少需要給出N+1 個(gè)可變的參數(shù)盯荤,而且N必須在0到20之間馋吗。
所以上面的:
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)就變成了metamacro_at20( __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)的樣子。
然后看函數(shù)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__)
這時(shí)需要看metamacro_head 的定義:
#define metamacro_head(...) \
metamacro_head_(__VA_ARGS__, 0)
根據(jù)定義的注釋:* Returns the first argument given. At least one argument must be provided.
可以得知廷雅,返回第一個(gè)參數(shù)耗美,而且至少需要一個(gè)參數(shù)。
進(jìn)一步去看宏定義metamacro_head_航缀,
#define metamacro_head_(FIRST, ...) FIRST
那么就可以知道此時(shí)的metamacro_head返回的是參數(shù)列表的第一個(gè)參數(shù)商架。
那么之前的宏的定義:
metamacro_at20( __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)返回的是參數(shù)列表中參數(shù)的個(gè)數(shù),就是__VA_ARGS__參數(shù)的個(gè)數(shù)芥玉。
也就是metamacro_at20 返回的是N蛇摸,而N是__VA_ARGS__的個(gè)數(shù)。
于是最上面的:metamacro_argcount(__VA_ARGS__) 就變成了metamacro_at20( __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)灿巧,所以:
(metamacro_foreach_cxt ## metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)=======>>>>
(metamacro_foreach_cxt ## metamacro_at20( __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1))(MACRO, SEP, CONTEXT, __VA_ARGS__)=======>>>>
(metamacro_foreach_cxt ## N)(MACRO, SEP, CONTEXT, __VA_ARGS__)
假如此時(shí)傳入的是self的話那么此時(shí)就會(huì)變成:
metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, __VA_ARGS__)這樣赶袄,也就是weakify(...) 轉(zhuǎn)換后的形式。
那就看一下metamacro_foreach_cxt1 的宏定義:
#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
而我們?cè)诙xweakify的時(shí)候傳遞的參數(shù)是:
#define weakify(...) \
rac_keywordify \
metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
所以我們的參數(shù)是:rac_weakify_,, __weak, __VA_ARGS__
metamacro_foreach_cxt1(rac_weakify_,, __weak, __VA_ARGS__)rac_weakify_(0,__weak ,__VA_ARGS__)
weakly(self)的時(shí)候就變成了抠藕,如下:
metamacro_foreach_cxt1(rac_weakify_,, __weak,self)rac_weakify_(0,__weak ,self)
那么接下來(lái)就需要看 宏定義rac_weakify_的:
rac_weakify_:
#define rac_weakify_(INDEX, CONTEXT, VAR) \
CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
那么此時(shí)的rac_weakify_(0,__weak ,self)就應(yīng)該寫成:
__weak __typeof__(self) self_weak_ = self
weakly(self)弱化后的self 就這樣實(shí)現(xiàn)了饿肺。
@strongify的定義:
先看strongify的定義:
#define strongify(...) \
rac_keywordify \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
metamacro_foreach(rac_strongify_,, __VA_ARGS__) \
_Pragma("clang diagnostic pop")
去除沒(méi)用的部分就剩下了:
metamacro_foreach(rac_strongify_,, __VA_ARGS__)部分,這部分的定義如下:
#define metamacro_foreach(MACRO, SEP, ...) \
metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__)
到了這里就是和之前的weakify部分一樣的了盾似。
就變成了metamacro_foreach_cxt(metamacro_foreach_iter,, rac_strongify_, __VA_ARGS__)
strongly(self)此時(shí)就變成了metamacro_foreach_cxt(metamacro_foreach_iter,, rac_strongify_, self)
#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
接下來(lái)就是:
metamacro_foreach_cxt ## 1(metamacro_foreach_iter,, rac_strongify_, self)
metamacro_foreach_cxt1(metamacro_foreach_iter,, rac_strongify_, self)
接下來(lái):
#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
======>
metamacro_foreach_cxt1(metamacro_foreach_iter,, rac_strongify_, self) === metamacro_foreach_iter(0, rac_strongify_, self)
接下來(lái)就是:metamacro_foreach_iter:
#define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG)
那么此時(shí)的metamacro_foreach_iter(0, rac_strongify_, self) 就變成了:
metamacro_foreach_iter(0, rac_strongify_, self) = rac_strongify_(0敬辣, self)
再看rac_strongify_ ,那么就是:
#define rac_strongify_(INDEX, VAR) \
__strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_);
那么此時(shí):
rac_strongify_(0零院, self)
=========>
__strong __typeof__(self) self = self_weak_
那么最后就變成了:
__weak __typeof__(self) self_weak_ = self
__strong __typeof__(self) self = self_weak_
需要注意的是:strong 必須在block中使用:
使用的方式如下:
__weak __typeof__ (self) self_weak_ = (self);
ViewController *VC = [[RootViewController alloc]init];
[VC successBlock:^{
__strong __typeof__(self) self = self_weak_;
}];
從上所述: