1.動態(tài)參數(shù)個(gè)數(shù)的計(jì)算
metamacro_argcount(...)
這個(gè)宏是用來計(jì)算參數(shù)個(gè)數(shù)的,其實(shí)就是根據(jù)
__VA_ARGS__
可變原則,以及參數(shù)占位原則來實(shí)現(xiàn)的
#define diy_argcount(...)
定義了上面這個(gè)宏,里面的...
就是__VA_ARGS__
,如果寫成
diy_argcount(1,2,3)
那么__VA_ARGS__
就是1,2,3
,稍微變化一下
#define diy_argcount_1(parm1,...)
#define diy_argcount(...) diy_argcount_1(__VA_ARGS__)
此時(shí)上面的diy_argcount_1
的__VA_ARGS__
就變成2,3
, parm1
就變成了1,再來看看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)
#define metamacro_at(N, ...) \
metamacro_concat(metamacro_at, N)(__VA_ARGS__)
假設(shè)我們代碼是metamacro_argcount(obj1,obj2,obj3)
那么根據(jù)上面的宏變換下,就是
metamacro_at20(obj1,obj2,obj3,20,19,....2,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_at20(obj1,obj2,obj3,20,19,....2,1)
中前面的20個(gè)參數(shù)逐個(gè)應(yīng)對_1,_2,_3...._20
這樣的變量,也及時(shí)相當(dāng)于
_0 = obj1,
_1 = obj2,
_2 = obj3,
_3 = 20,
_4 = 19
.
.
.
_19 = 4
這樣metamacro_head(__VA_ARGS__)
中的__VA_ARGS__
就是3,2,1
而metamacro_head
定義如下
#define metamacro_head_(FIRST, ...) FIRST
那么metamacro_head_ (3,2,1)
就是3
也就是有三個(gè)參數(shù)的輸入
2.@weakify(obj1,obj2,obj3)實(shí)現(xiàn)
如果weakify
只可以接受一個(gè)參數(shù),這樣的宏都會寫
#define weakify(_1) __weak __typeof__(_1) _1##_weak_ = (_1)
我們可以通過動態(tài)獲取參數(shù)個(gè)數(shù)的方法,拿到obj1, obj2, obj3
,再對他們每個(gè)rac_weakify_
簡化下RAC以后的宏定義
#define rac_weakify_(VAR) \
__weak __typeof__(VAR) VAR##_weak_ = (VAR);
定義
#define rac_weakify_20(N,SEP,...) rac_weakify_(N)\
SEP\
rac_weakify_19(__VA_ARGS__)
#define rac_weakify_19(N,SEP,...) rac_weakify_(N)\
SEP\
rac_weakify_18(__VA_ARGS__)
.
.
.
#define rac_weakify_1(N) rac_weakify_(N)
那么weakify
宏就可以寫成
#define weakify(...) (rac_weakify_##metamacro_argcount(__VA_ARGS__))(__VA_ARGS__)
而RAC為了區(qū)分在這類的宏在前面加個(gè)@,其實(shí)就是
#define weakify(...) autoreleasePool{} (rac_weakify_##metamacro_argcount(__VA_ARGS__))(__VA_ARGS__)
其中SEP
就是宏定義空字符,用來分開宏定義字符連接
關(guān)鍵點(diǎn)
假設(shè)定義#define macro1 左(
...
) 右(__VA_ARGS__
)
關(guān)鍵點(diǎn):宏中的...=> __VA_ARGS__
從左到右是全映射
而宏中右部分的__VA_ARGS__
映射到另一個(gè)宏時(shí),是逐個(gè)映射到變量,只有映射不到的時(shí)候,或者有剩余沒有映射到的參數(shù)才映射到...