1.自己對(duì)宏的評(píng)價(jià)
- 宏是C語言系統(tǒng)中最為有趣(通常被稱為強(qiáng)大)的部分诚卸,好的宏定義可以讓代碼簡(jiǎn)潔到極致瓜富,事半功倍的效果攒霹,當(dāng)然也會(huì)帶來調(diào)試的問題。
2.@weakify @strongify的分析
- 已經(jīng)有帖子分析過了扣泊,用自己的方式在寫一次近范,做個(gè)筆記。
- 結(jié)尾會(huì)附上參考閱讀的帖子
3.使用Xcode顯示預(yù)處理結(jié)果(用來判斷自己的分析結(jié)果)
-
Product > Perform Action > Preprocess "xxx.m"
-
在輔助編輯器(Assistant Editer)中延蟹,點(diǎn)擊preprocess
-
預(yù)處理后的代碼
4.只分析@weakify评矩,@strongify是一樣的
4.1列出會(huì)分析到的所有宏
- @關(guān)鍵字后面weakify的定義
#define weakify(...) \
rac_keywordify \
metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
- rac_keywordify,就是autoreleasepool {}
- 通過一個(gè)未使用的autoreleasepool {}阱飘,巧妙的為weakify添加@關(guān)鍵字
#if DEBUG
#define rac_keywordify autoreleasepool {}
#else
#define rac_keywordify try {} @catch (...) {}
#endif
- metamacro_foreach_cxt斥杜,weakify的實(shí)現(xiàn)
#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
- metamacro_argcount,返回傳入的可變參數(shù)個(gè)數(shù)
#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_concat沥匈,拼接兩個(gè)參數(shù)名
- metamacro_concat(a, _b)蔗喂,返回參數(shù)名為
a_b
#define metamacro_concat(A, B) \
metamacro_concat_(A, B)
- metamacro_foreach_cxt1,根據(jù)weakify(...)參數(shù)個(gè)數(shù)拼接后的宏(這里weakify(self)只有self一個(gè)參數(shù)所以為cxt1高帖,如果是兩個(gè)參數(shù)缰儿,則會(huì)對(duì)應(yīng)到metamacro_foreach_cxt2)
#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
- rac_weakify_,weakify(...)的真實(shí)實(shí)現(xiàn)
#define rac_weakify_(INDEX, CONTEXT, VAR) \
CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
- 關(guān)鍵字__weak散址,使用Xcode preprocess后為attribute((objc_ownership(weak)))
__weak 預(yù)處理后對(duì)應(yīng) __attribute__((objc_ownership(weak)))
4.2一步一步展開就明白了
- 原始宏
@weakify(self)
- 展開@weakify(self)乖阵,并替換參數(shù)
@rac_keywordify metamacro_foreach_cxt(rac_weakify_,, __weak, self)
- 替換rac_keywordify
-
@autoreleasepool {}
這就是為什么weakify前面可以寫@
關(guān)鍵字
@autoreleasepool {} metamacro_foreach_cxt(rac_weakify_,, __weak, self)
- 替換metamacro_foreach_cxt,并替換參數(shù)
@autoreleasepool {} metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(self))(rac_weakify_,, __weak, self)
- 替換metamacro_argcount(self)预麸,因?yàn)閭魅氲闹挥衧elf一個(gè)參數(shù)瞪浸,所以實(shí)際就是1
@autoreleasepool {} metamacro_concat(metamacro_foreach_cxt, 1)(rac_weakify_,, __weak, self)
- 替換metamacro_concat拼接宏參數(shù),得到下面結(jié)果
@autoreleasepool {} metamacro_foreach_cxt1(rac_weakify_,, __weak, self)
- 替換metamacro_foreach_cxt1吏祸,并替換參數(shù)
@autoreleasepool {} rac_weakify_(0, __weak, self)
- 替換rac_weakify_对蒲,并替換參數(shù)
@autoreleasepool {} __weak __typeof__(self) metamacro_concat(self, _weak_) = (self);
- 替換metamacro_concat拼接宏參數(shù)
@autoreleasepool {} __weak __typeof__(self) self_weak_ = (self);
- 替換__weak,得到最終結(jié)果(與Xcode preprocess后結(jié)果一致)
@autoreleasepool {} __attribute__((objc_ownership(weak))) __typeof__(self) self_weak_ = (self);
5.參考的文章
剖析@weakify贡翘、@strongify
Reactive Cocoa中@weakify和@strongify實(shí)現(xiàn)分析