概述
讲道理刚刚学RAC的时候点击宏进去的话其实是一脸懵逼的,然后自己看了下又看了几篇文章也有了一定的了解现在就简单的介绍下。
一样的从@weakify着手,我们点击进去会看到下面的代码,其中关于rac_keywordify是在我的同类的文章中讲过,这里就不介绍了,这里主要想记录下metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
//1、
#define weakify(...)
rac_keywordify
metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
其中...的意思宏定义中的省略号就是指一串数目不限的参数列表和__VA_ARGS__连用的话其实就是代表把...所代表的内容替换到__VA_ARGS__这个的位置。
所以我们去要去看的就是下面这个
//2、
metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
然后点击进去看,我们就会发现有下面这么个东西
//3、
#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...)
metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
我们这里就让@weakify里面的参数为self,来说明,这里把上面的metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)替换成下面的这个
//4、
metamacro_concat(metamacro_foreach_cxt,metamacro_argcount(__VA_ARGS__))(rac_weakify_,,_weak,self)
接着我们再去看下metamacro_concat,我们会发现下面的这个东西
//5、
#define metamacro_concat(A, B)
metamacro_concat_(A, B)
然后我们再点进去看,会发现其实这个宏就是做了一个拼接,不过这里用到了转换宏是需要注意的,这里其实就是将A和B拼在一起
//6、
#define metamacro_concat_(A, B) A ## B
接着我们再来看下metamacro_argcount(...)),这个有什么用?其实这个宏就是帮你计算出你括号里面有传进来了几个参数。就比如说metamacro_argcount(@"sss",@"qqq");这样的话得到的就是2,然后我们上面传入的是一个self,所以metamacro_argcount(self)是为1的,因为代码4当中的metamacro_argcount(__VA_ARGS__)中的__VA_ARGS__被替换成了self。于是我们把4的代码再进行替换就会得到下面的这个式子
//7、
metamacro_foreach_cxt ## 1 (rac_weakify_,,_weak,self)
其实就是变成了
//8、
metamacro_foreach_cxt1(rac_weakify_,
, __weak, self)
我们点击metamacro_foreach_cxt1进去看,会发现还有cxt2,3,4,5,6,7,8,等等一直到20
//9、
#define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT)
#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
#define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1)
metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0)
SEP
MACRO(1, CONTEXT, _1)
#define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2)
metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1)
SEP
MACRO(2, CONTEXT, _2)
#define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3)
metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2)
SEP
MACRO(3, CONTEXT, _3)
#define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4)
metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3)
SEP
MACRO(4, CONTEXT, _4)
我们需要关注的就是下面这一行
//10、
#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
也就是说其实就是替换成了
//11、
rac_weakify_(0,__weak,self)
所以最终我们还剩下最后一步,去看rac_weakify_这个宏,这里的INDEX只是第几个ctx的标记,没有什么作用
//12、
#define rac_weakify_(INDEX, CONTEXT, VAR)
CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
所以最终其实我们就是变成了
//13、
__weak __typeof__(self) self_weak_ = self
@weakify()括号里面传入的参数可以最多达到20个就是因为metamacro_foreach_cxt这个最多到20。我们往里面传入参数的话直接往括号里面写就好了。如果我们传入多个参数的话也会做多个参数的weak,其实实现起来就像递归一样举个例子,就比如说ctx3又去用了ctx2。
#define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2)
metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1)
SEP
MACRO(2, CONTEXT, _2)
还有就是需要注意的是@weakify在外界使用,@strongify是在block内部使用的,如果两者在外界使用没在block里面使用就会报错,因为这就好比转换成了下面的这个代码,self重复定义了。
__weak __typeof__ (self) self_weak_ = self;
__strong __typeof__(self) self = self_weak_;
接着对于@strongify其实道理是一样的只不过最终转换的是这样子的。
__strong __typeof__(self) self = self_weak_;
接着我们再去看下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)
再去看下metamacro_at,这里我们还是拿metamacro_argcount(self)举例子
#define metamacro_at(N, ...)
metamacro_concat(metamacro_at, N)(__VA_ARGS__)
也就是说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_concat(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_concat这个代表的是连接的意思,所以又变成了
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__)
其实也就是替换成了
metamacro_head(1)
再点击metamacro_head进去查看会发现下面的这个代码
#define metamacro_head(...)
metamacro_head_(__VA_ARGS__, 0)
然后我们再点击metamacro_head_进去查看,发现如下所示
#define metamacro_head_(FIRST, ...) FIRST
所以最后其实就是变成了下面所示
metamacro_head_(1)
所以得出的是1,如果有两个三个参数其实都是类似的只不过是metamacro_head(2,1)括号里面的内容改变了。
最后
以上就是懦弱小猫咪为你收集整理的RAC中的宏浅析的全部内容,希望文章能够帮你解决RAC中的宏浅析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复