@weakify和@strongify淺析

前言

在RAC中@weakify和@strongify可以實現(xiàn)_weak和_strong的效果,即在block內(nèi)部管理對self的引用劈猿,在項目中通常以下面這種形式展示出來

@weakify(self); // 定義了一個__weak的self_weak_變量 
[RACObserve(self, name) subscribeNext:^(NSString *name) { 
    @strongify(self); // 局域定義了一個__strong的self指針指向self_weak 
    self.textLabel.text = name; 
}];

看得多了就想知道它內(nèi)部到底是怎么實現(xiàn)的~

內(nèi)部實現(xiàn)

打開Xcode找到Product->PreformAction-Process "當(dāng)前使用@weakify或@strongify的文件",可以看到這兩個宏展開之后的最終效果如下:

 @autoreleasepool {} __attribute__((objc_ownership(weak))) __typeof__(self) self_weak_ = (self);;
 
  __attribute__((objc_ownership(strong))) __typeof__(self) self = self_weak_;

@autoreleasepool{}實現(xiàn)了添加@的效果筷黔,)attribute((objc_ownership(weak)))就是weak的實現(xiàn)仗颈,_typeof的作用是取類型,相當(dāng)于創(chuàng)建了歐引用self的self_weak的局部變量请祖。

attribute((objc_ownership(strong)))相當(dāng)于_strong,創(chuàng)建了self_weak的強引用,變量名為self

宏展開

以@weakify為例:

  • 第一層
#define weakify(...) \
    rac_keywordify \
    metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)

分析:

  1. rac_keywordify的宏定義是#define rac_keywordify autoreleasepool {},這么做是為了可以添加@~

  2. metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)刷晋,有多個參數(shù)慎陵,第一個參數(shù)是CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR),第二個參數(shù)沒有,第三個是weak蒙幻,最后__VA_ARGS__是多參數(shù)的意思,代表self胆筒,缺省號代表一個可以變化的參數(shù)表。使用保留名__VA_ARGS__把參數(shù)傳遞給宏抒和。當(dāng)宏的調(diào)用展開時彤蔽,實際的參數(shù)就傳遞給metamacro_foreach_cxt

  • 第二層

分解metamacro_foreach_cxt

#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
        metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)

__VA_ARGS__是可變參數(shù),獲取在...中傳入的N個參數(shù)

metamacro_argcount

metamacro_argcount這個宏用來獲得參數(shù)的個數(shù)镊辕,文檔說返回提供給該宏的參數(shù)個數(shù)(超過20個)蚁袭,至少一個必須提供,展開如下:

#define 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_at展開如下:

#define metamacro_at(20, self) \
        metamacro_concat(metamacro_at, N)(__VA_ARGS__)

因為metamacro_concat展開A ## B的意思卖哎,metamacro_at拼接參數(shù)N后變成如下樣子:

metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19,...)

截斷了前面20個參數(shù)因為...此時代表1

展開是這個:metamacro_head(1)删性,后面metamacro_head_(FIRST,...)FIRST,因為返回第一個,所以參數(shù)個數(shù)是1

回到metamacro_foreach_cxt就變成

metamacro_foreach_cxt##metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)

metamacro_argcount既然返回的是參數(shù)個數(shù)那么就可以變成這樣

metamacro_foreach_cxt##N(MACRO, SEP, CONTEXT, __VA_ARGS__)

N是參數(shù)個數(shù)维贺,在這里是1

metamacro_foreach_cxt1的實現(xiàn)實現(xiàn)是這樣的

#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)

最終可以寫成

metamacro_foreach_cxt1(rac_weakify_, , __weak, self) rac_weakify_(0,__weak,self)

@strongify原理也差不多,這里就不多說了

PS:@weakify幸缕、@strongify是不會聯(lián)想的,不會聯(lián)想weakify和strongify发乔,經(jīng)常使用可以把它們加入代碼段

小結(jié)

RAC中對宏的使用出神入化,想弄清楚還是看源碼多多推敲~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末起愈,一起剝皮案震驚了整個濱河市译仗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纵菌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笛辟,死亡現(xiàn)場離奇詭異序苏,居然都是意外死亡,警方通過查閱死者的電腦和手機忱详,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門匈睁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人航唆,你說我怎么就攤上這事。” “怎么了黎比?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長演闭。 經(jīng)常有香客問我,道長米碰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任虐译,我火速辦了婚禮,結(jié)果婚禮上漆诽,老公的妹妹穿的比我還像新娘。我一直安慰自己厢拭,他們只是感情好撇叁,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布陨闹。 她就那樣靜靜地躺著,像睡著了一般正林。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上觅廓,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天杈绸,我揣著相機與錄音,去河邊找鬼瞳脓。 笑死,一個胖子當(dāng)著我的面吹牛劫侧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播写妥,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼审姓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了扎筒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤奥溺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后症脂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡壶唤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年闸盔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迎吵。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡击费,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔫巩,到底是詐尸還是另有隱情,我是刑警寧澤圆仔,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站坪郭,受9級特大地震影響脉幢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嫌松,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望珊蟀。 院中可真熱鬧外驱,春花似錦育灸、人聲如沸磅崭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒋譬。三九已至,卻和暖如春癣漆,著一層夾襖步出監(jiān)牢的瞬間剂买,已是汗流浹背惠爽。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工婚肆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留坐慰,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓两残,卻偏偏與公主長得像把跨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子着逐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容