亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ReactiveCocoaTutorial[1]="神奇的Macros";

2019-11-14 20:42:51
字體:
來源:轉載
供稿:網友

  Reactive Cocoa Tutorial 系列,轉載請注明該文源地址 -- by sunny


  先說說RAC中必須要知道的宏:

  · RAC(TARGET, [KEYPATH, [NIL_VALUE]])

RAC(self.outputLabel, text) = self.inputTextField.rac_textSignal;

RAC(self.outputLabel, text, @"收到nil時就顯示我") = self.inputTextField.rac_textSignal;

  這個宏是最常用的,RAC()總是出現在等號左邊,等號右邊是一個RACSignal,表示的意義是將一個對象的一個屬性和一個signal綁定,signal每產生一個value(id類型),都會自動執行:

[TARGET setValue:value ?: NIL_VALUE forKeyPath:KEYPATH];

  數字值會升級為NSNumber *,當setValue:forKeyPath時會自動降級成基本類型(int, float ,BOOL等),所以RAC綁定一個基本類型的值是沒有問題的

 

  · RACObserve(TARGET, KEYPATH)

  作用是觀察TARGET的KEYPATH屬性,相當于KVO,產生一個RACSignal

  最常用的使用,和RAC宏綁定屬性:

RAC(self.outputLabel, text) = RACObserve(self.model, name);

  上面的代碼將label的輸出和model的name屬性綁定,實現聯動,name但凡有變化都會使得label輸出

 

  · @weakify(Obj)  @strongify(Obj)

  這對宏在 RACEXTScope.h 中定義,RACFramework好像沒有默認引入,需要單獨import

  他們的作用主要是在block內部管理對self的引用:

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

  這個宏為什么這么吊,前面加@,其實就是一個啥都沒干的@autoreleasepool {}前面的那個@,為了顯眼罷了。

  這兩個宏一定成對出現,先weak再strong

 

  除了RAC中常用宏的使用,有一些宏的實現方法也很值得觀摩。 


 

  舉個高級點的栗子

  要干的一件事,計算一個可變參數列表的長度。

  第一反應就是用參數列表的api,va_start va_arg va_end遍歷一遍計算個和,但仔細想想,對于可變參數這個事,在編譯前其實就已經確定了,代碼里括號里有多少個參數一目了然。

  RAC中Racmetamarcos.h中就有一系列宏來完成這件事,硬是在預處理之后就拿到了可變參數個數:

#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)

   這個宏由幾個工具宏一層層展開,現在模擬一下展開過程:

假如我們要計算的如下:

int count = metamacro_argcount(a, b, c);

于是乎第一層展開后:

int count = 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)

  再看metamacro_at的定義:

#define metamacro_at(N, ...) metamacro_concat(metamacro_at, N)(__VA_ARGS__)// 下面是metamacro_concat做的事(簡寫一層)#define metamacro_concat_(A, B) A ## B

  于是乎第二層展開后:

int count = metamacro_at20(a, b, c, 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__)

  于是乎第三層展開后,相當于截斷了前20個參數,留下剩下幾個:

int count = metamacro_head(3, 2, 1);

  這個metamacro_head:

#define metamacro_head(...) metamacro_head_(__VA_ARGS__, 0)#define metamacro_head_(FIRST, ...) FIRST

  后面加個0,然后取參數列表第一個,于是乎:

int count = 3;

  大功告成。

  反正我看完之后感覺挺震驚,宏還能這么用,這樣帶來的好處不止是將計算在預處理時搞定,不拖延到運行時惡心cpu;但更重要的是編譯檢查。比如某些可變參數的實現要求可以填2個參數,可以填3個參數,其他的都不行,這樣,也只有這樣的宏的實現,才能在編譯前就確定了錯誤。

 


 

   除了上面,還有一個神奇的宏的使用:

  當使用諸如RAC(self, outputLabel)或RACObserve(self, name)時,發現寫完逗號之后,輸入第二個PRoperty的時候會出現完全正確的代碼提示!這相當神奇。

  

探究一下,關鍵的關鍵是如下一個宏:

#define keypath(...) /    metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__))(keypath1(__VA_ARGS__))(keypath2(__VA_ARGS__))

  這個metamacro_argcount上面說過,是計算可變參數個數,所以metamacro_if_eq的作用就是判斷參數個數,如果個數是1就執行后面的keypath1,若不是1就執行keypath2。

  所以重點說一下keypath2:

#define keypath2(OBJ, PATH) /    (((void)(NO && ((void)OBJ.PATH, NO)), # PATH))

  乍一看真挺懵,先化簡,由于Objc里面keypath是諸如"outputLabel.text"的字符串,所以這個宏的返回值應該是個字符串,可以簡化成:

#define keypath2(OBJ, PATH) (???????, # PATH)

  先不管"??????"是啥,這里不得不說C語言中一個不大常見的語法(第一個忽略):

int a = 0, b = 0;
a = 1, b = 2;
int c = (a, b);

  這些都是逗號表達式的合理用法,第三個最不常用了,c將被b賦值,而a是一個未使用的值,編譯器會給出warning。

  去除warning的方法很簡單,強轉成void就行了:

int c = ((void)a, b);

  再看上面簡化的keypath2宏,返回的就是PATH的字符串字面值了(單#號會將傳入值轉成字面字符串)

  (((void)(NO && ((void)OBJ.PATH, NO)), # PATH))

  綠色字體部分對傳入的第一個參數OBJ和第二個正要輸入的PATH做了點操作,這也正是為什么輸入第二個參數時編輯器會給出正確的代碼提示。強轉void就像上面說的去除了warning。

  但至于為什么加入紅色字體部分的與NO做&&,我不太能理解,我測試時其實沒有紅色部分已經完成了功能,可能是作者為了屏蔽某些隱藏的問題吧。

  這個宏的巧妙的地方就在于使得編譯器以為我們要輸入“點”出來的屬性,保證了輸入值的合法性(輸了不存在的property直接報錯的),同時利用了逗號表達式取逗號最后值的語法返回了正確的keypath。

 

總之,RAC對宏的使用達到了很高的水平,還有諸如RACTuplePack,RACTupleUnpack的宏就不細說了,值得研究。

   PS:上面介紹的metamacro和@strongify等宏確切來說來自RAC依賴的extobjc,作者是Justin Spahr-Summers,正是RAC作者之一。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国内外成人免费激情在线视频网站| 日韩激情片免费| 欧美色图在线视频| 亚洲综合在线做性| 成人综合国产精品| 国产一区二区日韩精品欧美精品| 国内精品模特av私拍在线观看| 中文字幕在线视频日韩| 亚洲第一网中文字幕| 亚洲成人久久久久| xxav国产精品美女主播| 亚洲欧美国内爽妇网| 深夜福利国产精品| 91大神在线播放精品| 国产精品入口免费视| 日本不卡视频在线播放| 色yeye香蕉凹凸一区二区av| 日韩美女视频免费在线观看| 久久久精品电影| 精品国产999| 亚洲激情小视频| 成人福利免费观看| 亚洲热线99精品视频| 欧美日韩国产黄| 国产一区二区在线播放| 国产精品老女人视频| 欧美激情视频在线免费观看 欧美视频免费一| 久久精品久久久久电影| 国产在线精品播放| 久久久久久国产精品美女| 国产精品丝袜一区二区三区| 国产精品亚洲综合天堂夜夜| 国产亚洲欧美另类中文| 国产精品xxxxx| 亚洲欧美日韩图片| 欧美丝袜一区二区三区| 日韩在线一区二区三区免费视频| 亚洲国产精久久久久久久| 午夜精品理论片| 91免费国产视频| 亚洲精品自在久久| 欧美日韩xxxxx| 亚洲日本欧美日韩高观看| 欧美另类在线观看| 国产日韩换脸av一区在线观看| 在线观看久久av| 日本一欧美一欧美一亚洲视频| 久久久久女教师免费一区| 91高潮精品免费porn| 久久久久北条麻妃免费看| 成人av资源在线播放| 亚洲第一偷拍网| 日韩欧美一区二区在线| 国产一区红桃视频| 色妞久久福利网| 日韩极品精品视频免费观看| 亚洲一区二区久久久| 国产主播欧美精品| 国产日韩精品入口| 欧美中文字幕在线| 中文字幕日韩高清| 久久久久久91| 91视频8mav| 91成品人片a无限观看| 欧美在线影院在线视频| 国外视频精品毛片| 欧美人在线视频| 亚洲成色777777在线观看影院| 欧美色欧美亚洲高清在线视频| 国产精品美女www爽爽爽视频| 国产精品久久久久久久久久| 亚洲自拍在线观看| 久久亚洲春色中文字幕| 久久精品人人做人人爽| 欧美成人精品不卡视频在线观看| 国产成人极品视频| 国产精品稀缺呦系列在线| 亚洲精品日韩欧美| 中文字幕精品一区二区精品| 一本一道久久a久久精品逆3p| 亚洲欧美一区二区三区在线| 国产欧美一区二区三区久久人妖| 精品久久久久久久久久久久久久| 成人黄色免费网站在线观看| 日本久久久久久久久久久| 亚洲网站在线观看| 久久久免费精品| 欧美性猛交99久久久久99按摩| 欧美亚洲成人免费| 精品久久香蕉国产线看观看gif| 精品久久久精品| 成人有码在线视频| 久久精品久久久久久国产 免费| 亚洲视频欧美视频| 96精品视频在线| 亚洲第一国产精品| 欧美极品少妇xxxxⅹ喷水| 日韩成人久久久| 日韩在线观看免费网站| 亚洲第一网站免费视频| 欧美精品成人91久久久久久久| 色婷婷成人综合| 日本精品视频在线观看| 91麻豆桃色免费看| 91爱爱小视频k| 欧美精品情趣视频| 欧美精品久久久久久久久久| 日韩最新在线视频| 国产精品偷伦免费视频观看的| 一区二区三区视频免费在线观看| 黑人巨大精品欧美一区二区一视频| 国产精品人成电影在线观看| 亚洲精品小视频在线观看| 国产精品日韩欧美综合| 欧美电影免费观看网站| 日韩av影院在线观看| 久久人人爽人人爽人人片av高清| 91久久国产综合久久91精品网站| 国产成人精品一区二区| 日本欧美一二三区| 日韩欧美aⅴ综合网站发布| 国产精品欧美激情在线播放| 国产精品第2页| 国产有码在线一区二区视频| 欧美日韩在线观看视频| 久久免费精品日本久久中文字幕| 久久中文字幕国产| 一本大道香蕉久在线播放29| 91免费观看网站| 欧美激情视频一区二区三区不卡| 伊人精品在线观看| 国产精品网红福利| 日韩欧美视频一区二区三区| 欧美限制级电影在线观看| 成人激情视频在线播放| 欧美亚洲视频在线观看| 97精品国产aⅴ7777| 欧美午夜激情小视频| 青青草99啪国产免费| 国产精品视频免费在线| 综合136福利视频在线| 久久人人爽人人爽人人片av高请| 成人黄色影片在线| 在线观看国产精品日韩av| 欧美激情一二区| 欧美日韩视频免费播放| 国产91色在线| 亚洲久久久久久久久久久| 日韩福利视频在线观看| 美女视频久久黄| 国产97在线视频| 欧美激情精品久久久久久| 色偷偷88888欧美精品久久久| 久久在线精品视频| 国产主播精品在线| 欧美性高潮在线| 亚洲第一中文字幕在线观看| 亚洲第一av在线| 日韩精品亚洲精品| 色爱av美腿丝袜综合粉嫩av| 国产欧美日韩视频| 亚洲一区中文字幕| 色综合老司机第九色激情| 91精品国产91久久久久久|