RAC用法詳解,一看就懂萎河,以及RAC中的循環(huán)引用

最近一段時(shí)間開始研究RAC荔泳,它集響應(yīng)式編程,函數(shù)式編程和鏈?zhǔn)骄幊逃谝簧砼氨俜降恼f(shuō)玛歌,ReactiveCocoa(其簡(jiǎn)稱為RAC)是由GitHub開源的一個(gè)應(yīng)用于iOS和OS X開發(fā)的新框架,大大簡(jiǎn)化了我們的代碼擎椰,提高了代碼的安全性支子,很多處理已經(jīng)幫我們做好了,比如block里面循環(huán)引用的問(wèn)題达舒,最終在我們?nèi)∠嗛喌哪且粍x那值朋,幫我們打斷了循環(huán)引用。

首先巩搏,如何安裝RAC昨登,直接通過(guò)pods進(jìn)行安裝即可,現(xiàn)在RAC已經(jīng)支持swift贯底,這里我們就直接基于OC的講解吧丰辣。

推薦RAC的版本3.0.0,通過(guò)pod安裝好后禽捆,build一下看看有沒有問(wèn)題糯俗,一般情況式?jīng)]啥問(wèn)題的。

現(xiàn)在一起開啟RAC的愉快之旅吧睦擂。

由于RAC的功能實(shí)在是太強(qiáng)大了得湘,涉及到一整套的編程邏輯,比如數(shù)據(jù)結(jié)構(gòu)方面顿仇,增加了元祖類型RACTuple淘正,RACSequence;數(shù)據(jù)處理方面,快速遍歷數(shù)組臼闻,字典(非常好的字典轉(zhuǎn)模型設(shè)計(jì))鸿吆,監(jiān)聽各種事件,文本框輸入述呐,代替通知惩淳,代理,KVO等等,網(wǎng)絡(luò)事件的處理,比如一個(gè)頁(yè)面多個(gè)請(qǐng)求完成后刷新頁(yè)面等等思犁,還有非常牛逼的宏(當(dāng)然我沒看懂代虾,不建議大家去看,會(huì)用就好了激蹲,看了會(huì)瘋掉的)棉磨,列舉了這么多,其實(shí)最根本的就是信號(hào)的處理学辱,所有的事件都是先轉(zhuǎn)化成一個(gè)信號(hào)RACSignal乘瓤,再訂閱信號(hào)來(lái)完成的。

知識(shí)點(diǎn)一:

數(shù)據(jù)結(jié)構(gòu)策泣,元祖類衙傀,RACTuple,比較類似于OC中的數(shù)組萨咕,用法上也大同小異统抬,可以存放任何類型的對(duì)象。

RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"aaa",@"bbb",@(123)]];

知識(shí)點(diǎn)二:快速遍歷數(shù)組

數(shù)據(jù)結(jié)構(gòu)任洞,RACSequence蓄喇,用于代理NSArray,NSDictionary交掏,主要用途是進(jìn)行快速遍歷累驮,最常用的場(chǎng)景就是字典轉(zhuǎn)模型让虐。

NSArray *arr = @[@"abc",@"bbb",@123];

RACSequence *requence = arr.rac_sequence; // ?字典或數(shù)組都可以直接轉(zhuǎn)化成RACSequence類型的對(duì)象

// 遍歷

RACSignal *signal = requence.signal; // 再拿到這個(gè)對(duì)象的信號(hào)屬性進(jìn)行遍歷

[signal subscribeNext:^(id? _Nullable x) {NSLog(@"%@",x);}];

// 快速寫法:

[arr.rac_sequence.signal subscribeNext:^(id? _Nullable x) {}];

知識(shí)點(diǎn)三:快速遍歷字典

// 字典

NSDictionary *dict = @{@"name":@"Hank",@"age":@18};

// 字典轉(zhuǎn)集合,遍歷厌衔,其中的x其實(shí)就是元祖類型真友,拿到元祖RACTuple即可進(jìn)行拆包處理

[dict.rac_sequence.signal subscribeNext:^(id? _Nullable x) {

//? ? ? ? NSLog(@"%@",x);

// 發(fā)送了元祖類型 RACTwoTuple

//? ? ? ? RACTwoTuple *tuple = (RACTwoTuple *)x;

//? ? ? ? NSString *key = tuple[0];

//? ? ? ? NSString *value = tuple[1];

// 宏挪鹏,用于解析元祖,參數(shù):需要解析的元祖见秽,拆包去處鍵值數(shù)據(jù)

RACTupleUnpack(NSString *key,NSString *value) = x;

NSLog(@"%@%@",key,value);

}];

知識(shí)點(diǎn)四:舉例應(yīng)用場(chǎng)景:快速遍歷,數(shù)據(jù)轉(zhuǎn)模型并封裝成數(shù)組

// 解析plist文件

NSString *filePath = [[NSBundle mainBundle]pathForResource:@"KFC.plist" ofType:nil];

NSArray *dictArray = [[NSArray alloc]initWithContentsOfFile:filePath];

// 字典轉(zhuǎn)模型讨盒,解決方案一

//? ? NSMutableArray *array = [[NSMutableArray alloc]init];

//? ? [dictArray.rac_sequence.signal subscribeNext:^(NSDictionary *? _Nullable x) {

//? ? ? ? KFC *kfc = [KFC KFCWithDict:x];

//? ? ? ? [array addObject:kfc];

//? ? }];

// 解決方案二:通過(guò)映射解取,可以知道里面是字典,所以寫字典

// 會(huì)將集合中的所有元素value映射成新的對(duì)象[KFC KFCWithDict:value]返顺,然后包裝在一個(gè)數(shù)組里面

NSArray *arr = [[dictArray.rac_sequence map:^id _Nullable(NSDictionary * value) {

// 返回一個(gè)模型

return [KFC KFCWithDict:value];

// 轉(zhuǎn)成數(shù)組禀苦,拿到數(shù)據(jù)直接用是不是很方便啊K烊怠U穹Α!

}]array];

NSLog(@"%@",arr);

知識(shí)點(diǎn)五: 取代代理秉扑,監(jiān)聽某個(gè)類的事件

一般我們?cè)跈?quán)衡數(shù)據(jù)回調(diào)時(shí)慧邮,會(huì)傾向于使用block進(jìn)行回調(diào),但是對(duì)于一些事件的處理,比如點(diǎn)擊事件误澳,去重寫block或者代理耻矮,顯得十分麻煩,這里推薦使用RAC來(lái)解決脓匿。

比如淘钟,監(jiān)聽一個(gè)類的點(diǎn)擊事件或者某個(gè)事件的執(zhí)行宦赠,

// 1.代替代理:RACSubject

// 監(jiān)聽blueView里面的哪個(gè)方法的調(diào)用

[[self.blueView rac_signalForSelector:@selector(laile:)]subscribeNext:^(RACTuple * _Nullable x) {

NSLog(@"dianjile:%@",x);

}];

[[self.blueView rac_signalForSelector:@selector(btnClick:)]subscribeNext:^(RACTuple * _Nullable x) {

NSLog(@"dianjile:%@",x);

}];

}

知識(shí)點(diǎn)六:取代KVO

原生的KVO是將監(jiān)聽和監(jiān)聽后的處理分開陪毡,并且還要在一個(gè)類的dealloc方法里面進(jìn)行注銷觀察者,顯得非常麻煩勾扭,而RAC很好的幫我們處理好了一切毡琉,見下面:

// 監(jiān)聽方案一:

[_blueView rac_observeKeyPath:@"frame" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {

// 監(jiān)聽的回調(diào)

// 好處:將多個(gè)監(jiān)聽分開,也不需要擔(dān)心觀察者的移除

NSLog(@"value:%@---change:%@",value,change);

}];

// 監(jiān)聽方案2:

// 創(chuàng)建一個(gè)監(jiān)聽的信號(hào)

//? ? [[_blueView rac_valuesForKeyPath:@"frame" observer:nil

//? ? ? ] subscribeNext:^(id? _Nullable x) {

//? ? ? ? NSLog(@"%@",x);

//? ? }];

知識(shí)點(diǎn)七:監(jiān)聽當(dāng)前控制器的某個(gè)事件:

// 代替Controller的監(jiān)聽事件

[[_btn rac_signalForControlEvents:(UIControlEventTouchUpInside)]subscribeNext:^(__kindof UIControl * _Nullable x) {

NSLog(@"%@",x);

}];

知識(shí)點(diǎn)八:取代通知中心

// 代理通知

[[[NSNotificationCenter defaultCenter]rac_addObserverForName:UIKeyboardWillShowNotification object:nil]subscribeNext:^(NSNotification * _Nullable x) {

// 全部轉(zhuǎn)化成了信號(hào)

NSLog(@"%@",x);

}];

知識(shí)點(diǎn)九:監(jiān)聽文本框的輸入

// 監(jiān)聽文本框:拿到文本框輸入的每次的值

[_textView.rac_textSignal subscribeNext:^(NSString * _Nullable x) {

NSLog(@"%@",x);

}];

知識(shí)點(diǎn)十:RAC的timer計(jì)時(shí)器

原生的NSTimer用起來(lái)比較麻煩, 創(chuàng)建后需要手動(dòng)的停止妙色,釋放桅滋,而RAC也很好的幫我們處理好了一切:

// RAC的timer

[[RACSignal interval:1.0 onScheduler:[RACScheduler scheduler]]subscribeNext:^(NSDate * _Nullable x) {

NSLog(@"%@",[NSThread currentThread]);

}];

知識(shí)點(diǎn)十一:RAC處理網(wǎng)絡(luò)請(qǐng)求事件,比如一個(gè)頁(yè)面有多個(gè)接口身辨,需要一起刷新UI時(shí)丐谋。

/ 請(qǐng)求數(shù)據(jù)? ? RACSignal *signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id_Nonnull subscriber) {? ??

? ? // 請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)? ? ? ? NSLog(@"請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù) 1");? ? ?

?? // 發(fā)送數(shù)據(jù)? ? ? ? [subscriber sendNext:@"發(fā)送數(shù)據(jù) 1"];? ? ??

? return nil;??

? }];? ? ??

? RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id_Nonnull subscriber) {

// 請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)

NSLog(@"請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù) 2");

// 發(fā)送數(shù)據(jù)

[subscriber sendNext:@"發(fā)送數(shù)據(jù) 2"];

return nil;

}];

// 訂閱信號(hào)后就會(huì)收到信號(hào)發(fā)出的內(nèi)容

//? ? [signal1 subscribeNext:^(id? _Nullable x) {

//? ? ? ? NSLog(@"處理數(shù)據(jù) 1");

//? ? }];

// 數(shù)組:存放信號(hào)

// 當(dāng)數(shù)組中所有信號(hào)都發(fā)送了數(shù)據(jù),才會(huì)執(zhí)行selector煌珊,必須帶參,參數(shù)是sendNext發(fā)送過(guò)來(lái)的号俐,必須和信號(hào)一一對(duì)應(yīng)

// 參數(shù):每個(gè)信號(hào)發(fā)送的數(shù)據(jù),這里必須要帶參數(shù)定庵,不然會(huì)崩潰

[self rac_liftSelector:@selector(updateUIWithOneData:twoData:) withSignalsFromArray:@[signal1,signal2]];

知識(shí)點(diǎn)十二:RAC里面的宏

RAC里面的宏可以分為以下幾類:

/**

* RAC,給某個(gè)對(duì)象綁定一個(gè)屬性

* RACObserver吏饿,監(jiān)聽某個(gè)對(duì)象的屬性

* RACTuplePack:將數(shù)據(jù)打包成RACTuple

* RACTupleUnpack: 將RAC元祖解包成數(shù)據(jù)

*/

比如RAC宏用法:

// 監(jiān)聽文本框內(nèi)容

//? ? [self.textfield.rac_textSignal subscribeNext:^(NSString * _Nullable x) {

//? ? ? ? _label.text = x;

//? ? }];

// 宏RAC,給某個(gè)對(duì)象的某個(gè)屬性綁定信號(hào),一旦信號(hào)產(chǎn)生數(shù)據(jù)蔬浙,就會(huì)將內(nèi)容賦值給屬性

RAC(_label,text) = self.textfield.rac_textSignal;

// 監(jiān)聽某個(gè)對(duì)象的某個(gè)屬性猪落,返回信號(hào)

// 只要這個(gè)對(duì)象的屬性發(fā)生變化,信號(hào)就發(fā)送數(shù)據(jù)

[RACObserve(self.label, text)subscribeNext:^(id? _Nullable x) {

NSLog(@"%@",x);

}];

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末畴博,一起剝皮案震驚了整個(gè)濱河市笨忌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌俱病,老刑警劉巖官疲,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異庶艾,居然都是意外死亡袁余,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門咱揍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)颖榜,“玉大人,你說(shuō)我怎么就攤上這事⊙谕辏” “怎么了噪漾?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)且蓬。 經(jīng)常有香客問(wèn)我欣硼,道長(zhǎng),這世上最難降的妖魔是什么恶阴? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任诈胜,我火速辦了婚禮,結(jié)果婚禮上冯事,老公的妹妹穿的比我還像新娘焦匈。我一直安慰自己,他們只是感情好昵仅,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布缓熟。 她就那樣靜靜地躺著,像睡著了一般摔笤。 火紅的嫁衣襯著肌膚如雪够滑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天吕世,我揣著相機(jī)與錄音彰触,去河邊找鬼。 笑死寞冯,一個(gè)胖子當(dāng)著我的面吹牛渴析,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吮龄,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼俭茧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了漓帚?” 一聲冷哼從身側(cè)響起母债,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎尝抖,沒想到半個(gè)月后毡们,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昧辽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年衙熔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搅荞。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡红氯,死狀恐怖框咙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情痢甘,我是刑警寧澤喇嘱,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站塞栅,受9級(jí)特大地震影響者铜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜放椰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一作烟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庄敛,春花似錦俗壹、人聲如沸科汗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)头滔。三九已至怖亭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坤检,已是汗流浹背兴猩。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留早歇,地道東北人倾芝。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像箭跳,于是被迫代替她去往敵國(guó)和親晨另。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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