1. 來兩個(gè)簡(jiǎn)單的宏定義
#define metamacro_head(FIRST,..., 0) FIRST
意義比較明顯沒難度取第一個(gè)傳入的參數(shù);如 metamacro_head("a","b","c");取值為"a"
#define metamacro_concat_(A, B) A ## B
“##” 在宏定義里面表示字符的鏈接;metamacro_concat_("test","1") 張開后為字符串"test1";所以該宏業(yè)很簡(jiǎn)單,我們知道是參數(shù)的拼接了。
用的稍微復(fù)制點(diǎn)
2. 宏的調(diào)試
我們知道從代碼到可執(zhí)行會(huì)經(jīng)歷,1.預(yù)處理替換;2.詞法分析;3.語法分析;4。IRCode生成;5.再到針對(duì)平臺(tái)的匯編; 6.生成o文件; 7.生成可執(zhí)行文件?,F(xiàn)在我們關(guān)注的是第一個(gè)步驟。這樣也能方便我們查看替換后的效果。雖然不能斷點(diǎn)調(diào)試。
- (void)viewDidLoad {
[super viewDidLoad];
metamacro_head("a","b","c");
}
2.1 預(yù)處理替換前

2.2 預(yù)處理替換后
- (void)viewDidLoad {
[super viewDidLoad];
"a";
}
//metamacro_head("a","b","c"); 被替換為“a”了。
3. 繼續(xù)深入
3.1 簡(jiǎn)單定義
#define metamacro_at0(...) metamacro_head(__VA_ARGS__)
metamacro_at0可以看出metamacro_head一樣。
#define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__)
metamacro_at1("a","b","c"); 對(duì)號(hào)入座 "a"=> _0; "b","c"=>... ; 三個(gè)點(diǎn)表示參數(shù)可以無線擴(kuò)展,"VA_ARGS"表宏定義頭的可變參數(shù)就是那三個(gè)點(diǎn);我們展開metamacro_at1("a","b","c");
宏就變成了metamacro_head("b","c");那么根據(jù)上面描述我們知道m(xù)etamacro_head是取第一個(gè)參數(shù),因此metamacro_at1("a","b","c")的值是"b"。
3.2 繼續(xù)推導(dǎo)
#define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__)
#define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__)
..............
#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__)
可以知道m(xù)etamacro_at + 整數(shù),整數(shù)是多少就是該宏取到第幾位參數(shù)!
3.2 抽象 “metamacro_at + 整數(shù)”
#define metamacro_at(N, ...) \
metamacro_concat(metamacro_at, N)(__VA_ARGS__)
舉例:
metamacro_at(1,"a","b","c");我們知道m(xù)etamacro_concat為兩個(gè)產(chǎn)生拼接,那么metamacro_at(1,"a","b","c"),展開為metamacro_at1("a","b","c");那我們就知道了其結(jié)果為"b";metamacro_at2(,"a","b","c"),展開后值就是"c"了。依次類推就容易明白metamacro_at(N, ...), 是取后面可變參數(shù)"..."的第N個(gè)參數(shù)了[N從0開始計(jì)算]。
到現(xiàn)在為止我們可以獲取宏定義參數(shù)的任何為止的參數(shù)了!
4.計(jì)算宏參數(shù)個(gè)數(shù)
4.1 metamacro_argcount
也就是我們今天的主角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)
4.2 metamacro_argcount推導(dǎo)
經(jīng)過我們上面的分析已知道曉metamacro_at的含義。
舉例:
metamacro_argcount("a","b","c")
=>
metamacro_at(20, "a","b","c", 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
=>
3
“3”,便是我們所傳入?yún)?shù)的個(gè)數(shù),目前該宏設(shè)計(jì)為最多能傳入20個(gè)參數(shù)。
4.3 巧妙的設(shè)計(jì):
metamacro_at19(20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
含義:metamacro_at19表示取第19號(hào)參數(shù),第20個(gè)也就是最后一位參數(shù)1。
metamacro_at20(20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
含義:我們有1到20總共20個(gè)參數(shù),取不到參數(shù)值,因?yàn)閙etamacro_at20取的是第20號(hào)[從0算起],第21個(gè)參數(shù)。
metamacro_at20("a",20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
含義:metamacro_at20是取第21個(gè)參數(shù)的,現(xiàn)在我們有21個(gè)參數(shù),取到的值是多少呢?很顯然第21個(gè)參數(shù)為最后1,自己從頭開始數(shù)一數(shù);
metamacro_at20("a","b",20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
含義:現(xiàn)在我們有22個(gè)參數(shù)而metamacro_at20是取第21個(gè)參數(shù),我們數(shù)過來就知道了結(jié)果為2;
到這里是不是恍然大悟。只要我們填的參數(shù)不超過20個(gè)就能通過metamacro_argcount宏算出所傳入的參數(shù)個(gè)數(shù)!