RAC稍深入-適合新手學(xué)習(xí)RAC

繼續(xù)完成RAC的坑


前言

經(jīng)過上篇文章的學(xué)習(xí)腋逆,相信不少讀者已經(jīng)熟悉了RAC的基本用法研侣,可以嘗試在以后的開發(fā)中不用add target語句了回溺。這篇文章將稍微深入一點了解RAC的更多功能以及適用場合液斜。

什么是信號

RAC的核心就是信號矫膨,即RACSignal

信號可以看做是傳遞信號的工具瘦材,當(dāng)數(shù)據(jù)變化時厅须,信號就會發(fā)送改變的信息,以通知信號的訂閱者執(zhí)行方法食棕。

熱/冷信號

默認一個信號都是冷信號朗和,也就是值改變了错沽,也不會觸發(fā),只有訂閱了這個信號例隆,這個信號才會變?yōu)闊嵝盘柹啵蹈淖兞瞬艜|發(fā)。

自己動手寫一個RACSignal

//創(chuàng)建信號
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@"signal"];
    [subscriber sendCompleted];
    return nil;
}];

//訂閱信號
[signal subscribeNext:^(id x) {
    NSLog(@"x = %@", x);
} error:^(NSError *error) {
    NSLog(@"error = %@", error);
} completed:^{
    NSLog(@"completed");
}];

這是一個信號從創(chuàng)建到接收的完整過程镀层,我們接下來看看控制臺輸出了什么镰禾。

2016-01-05 14:33:06.106 RACStudyTest[895:38671] x = signal
2016-01-05 14:33:06.106 RACStudyTest[895:38671] completed

可以看到,創(chuàng)建信號時我們sent了一個signal唱逢,在我們訂閱subscribeNext時存儲在x中的就是這個字符串signal吴侦。從這里看出來,不但我們可以給訂閱者傳遞字符串坞古,只要是一個類一個對象我們都可以傳遞备韧。

另一方面控制臺輸出了completed說明訂閱信號部分的completed塊下得方法也被執(zhí)行了,這是因為餓哦在創(chuàng)建時發(fā)送完signal后又發(fā)送了一個completed痪枫。同理织堂,error下得方法我們也可以這樣調(diào)用。

融匯貫通一下奶陈,我們之前學(xué)的所有RAC的用法就是一個創(chuàng)建信號訂閱信號的過程易阳!

信號的處理

map

這里的map不是地圖,而是映射的意思吃粒,就是創(chuàng)建一個訂閱者的映射并且返回數(shù)據(jù)潦俺,具體用法我們來看代碼。

[[self.textFild.rac_textSignal map:^id(id value) {
    NSLog(@"%@", value);
    return @1;
}] subscribeNext:^(id x) {
    NSLog(@"%@", x);
}];

在TextFild控件中輸入good徐勃,輸出:

2016-01-05 15:02:15.180 RACStudyTest[1418:57245] 1
2016-01-05 15:02:21.710 RACStudyTest[1418:57245] g
2016-01-05 15:02:21.711 RACStudyTest[1418:57245] 1
2016-01-05 15:02:22.954 RACStudyTest[1418:57245] go
2016-01-05 15:02:22.955 RACStudyTest[1418:57245] 1
2016-01-05 15:02:23.464 RACStudyTest[1418:57245] goo
2016-01-05 15:02:23.464 RACStudyTest[1418:57245] 1
2016-01-05 15:02:23.705 RACStudyTest[1418:57245] good
2016-01-05 15:02:23.705 RACStudyTest[1418:57245] 1  

還是之前那個監(jiān)聽textfild編輯變化的例子事示,可以看到,當(dāng)信號被訂閱變成熱信號后僻肖,這里的map構(gòu)造的映射塊value的值就是控件中的字符變化肖爵,而訂閱者x的值就是映射者的返回值1。

根據(jù)這個功能我們就可以對我們監(jiān)測的東西和我們需求的東西進行轉(zhuǎn)換檐涝。比如監(jiān)聽了字符串變化遏匆,我們需要的時變化后的字符串長度而不是變化的字符串本身,則可以在map的返回值中返回text.length谁榜,就可以實時捕獲到字符串長度;甚至做一個映射表凡纳,將各個變化進行一對一或者一對多或者多對一的處理窃植。

filter

filter就是過濾,它可以幫助你篩選出你需要的信號變化荐糜。

[[self.textFild.rac_textSignal filter:^BOOL(NSString *value) {
    return [value length] > 3;
}] subscribeNext:^(id x) {
    NSLog(@"x = %@", x);
}];

輸入goodnight巷怜,輸出:

2016-01-05 15:18:20.492 RACStudyTest[1490:66721] x = good
2016-01-05 15:18:27.917 RACStudyTest[1490:66721] x = goodn
2016-01-05 15:18:28.129 RACStudyTest[1490:66721] x = goodni
2016-01-05 15:18:28.433 RACStudyTest[1490:66721] x = goodnig
2016-01-05 15:18:28.930 RACStudyTest[1490:66721] x = goodnigh
2016-01-05 15:18:29.155 RACStudyTest[1490:66721] x = goodnight

上述例子是在字符串長度大于3時才會輸出變換后的字符串葛超。

take/skip/repeat

take是獲取,skip是跳過延塑,這兩個方法后面跟著的都是NSInteger绣张。所以take 2就是獲取前兩個信號,skip 2就是跳過前兩個关带。repeat是重復(fù)發(fā)送信號侥涵。

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@"1"];
    [subscriber sendNext:@"2"];
    [subscriber sendNext:@"3"];
    [subscriber sendNext:@"4"];
    [subscriber sendNext:@"5"];
    [subscriber sendCompleted];
    return nil;
}] take:2];

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

這個demo只會輸出前兩個信號1和2還有完成信號completed,skip,repeat同理宋雏。

相似的還有takeLast takeUntil takeWhileBlock skipWhileBlock skipUntilBlock repeatWhileBlock都可以根據(jù)字面意思來理解芜飘。

delay

延時信號,顧名思義磨总,即延遲發(fā)送信號嗦明。

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@"delay"];
    [subscriber sendCompleted];
    return nil;
}] delay:2];

NSLog(@"tag");

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

輸出:

2016-01-05 15:27:55.908 RACStudyTest[1543:71256] tag
2016-01-05 15:27:58.102 RACStudyTest[1543:71256] delay

看時間可以發(fā)現(xiàn)訂閱者延遲了2秒才收到信號打印出x的值。PS:還有0.2s誤差是因為運行到不同代碼行的時間差

throttle

節(jié)流蚪燕,在我們做搜索框的時候娶牌,有時候需求的時實時搜索,即用戶每每輸入字符馆纳,view都要求展現(xiàn)搜索結(jié)果诗良。這時如果用戶搜索的字符串較長,那么由于網(wǎng)絡(luò)請求的延時可能造成UI顯示錯誤厕诡,并且多次不必要的請求還會加大服務(wù)器的壓力累榜,這顯然是不合理的,此時我們就需要用到節(jié)流灵嫌。

[[[self.textFild rac_textSignal] throttle:0.5] subscribeNext:^(id x) {
    NSLog(@"%@", x);
}];

加了節(jié)流管道壹罚,后面跟上了類型為NSTimeInterval的參數(shù)后,只有0.5S內(nèi)信號不產(chǎn)生變化才會發(fā)送請求寿羞,這樣快速的輸入也不會造成多次輸出猖凛。

distinctUntilChanged

網(wǎng)絡(luò)請求中為了減輕服務(wù)器壓力,無用的請求我們應(yīng)該盡可能不發(fā)送绪穆。distinctUntilChanged的作用是使RAC不會連續(xù)發(fā)送兩次相同的信號辨泳,這樣就解決了這個問題。

[[[self.textFild rac_textSignal] distinctUntilChanged] subscribeNext:^(id x) {
    NSLog(@"%@", x);
}];   

timeout

超時信號玖院,當(dāng)超出限定時間后會給訂閱者發(fā)送error信號菠红。

RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [[RACScheduler mainThreadScheduler] afterDelay:3 schedule:^{
        [subscriber sendNext:@"delay"];
        [subscriber sendCompleted];
    }];
    return nil;
}] timeout:2 onScheduler:[RACScheduler mainThreadScheduler]];

[signal subscribeNext:^(id x) {
    NSLog(@"%@", x);
} error:^(NSError *error) {
    NSLog(@"%@", error);
}];

輸出:

2016-01-05 15:41:58.686 RACStudyTest[1604:76716] Error Domain=RACSignalErrorDomain Code=1 "The operation couldn’t be completed. (RACSignalErrorDomain error 1.)"

由于在創(chuàng)建信號是限定了延遲3秒發(fā)送,但是加了timeout2秒的限定难菌,所以這一定是一個超時信號试溯。這個信號被訂閱后,由于超時郊酒,不會執(zhí)行訂閱成功的輸出x方法遇绞,而是跳到error的塊輸出了錯誤信息键袱。timeout在用RAC封裝網(wǎng)絡(luò)請求時可以節(jié)省不少的代碼量。

ignore

忽略信號摹闽,指定一個任意類型的量(可以是字符串蹄咖,數(shù)組等),當(dāng)需要發(fā)送信號時講進行判斷付鹿,若相同則該信號會被忽略發(fā)送澜汤。

[[[self.textFild rac_textSignal] ignore:@"good"] subscribeNext:^(id x) {
    NSLog(@"%@", x);
}];

總結(jié)

這篇文章比上一篇稍稍深入了RAC的附加功能,但還有很多例如扁平映射flattenMap倘屹,Signal of Signals都沒有提到银亲,RAC的東西實在太多太多,我說的也僅僅是九牛一毛纽匙。我將繼續(xù)研究RAC的深入用法务蝠,并發(fā)文給大家介紹。如果文中有什么錯誤烛缔,也希望大家給我指出來馏段,我將萬分感謝。也歡迎來我的博客看看践瓷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末院喜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子晕翠,更是在濱河造成了極大的恐慌喷舀,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淋肾,死亡現(xiàn)場離奇詭異硫麻,居然都是意外死亡,警方通過查閱死者的電腦和手機樊卓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門拿愧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人碌尔,你說我怎么就攤上這事浇辜。” “怎么了唾戚?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵柳洋,是天一觀的道長。 經(jīng)常有香客問我叹坦,道長膳灶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任立由,我火速辦了婚禮轧钓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘锐膜。我一直安慰自己毕箍,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布道盏。 她就那樣靜靜地躺著而柑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪荷逞。 梳的紋絲不亂的頭發(fā)上媒咳,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機與錄音种远,去河邊找鬼涩澡。 笑死,一個胖子當(dāng)著我的面吹牛坠敷,可吹牛的內(nèi)容都是我干的妙同。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼膝迎,長吁一口氣:“原來是場噩夢啊……” “哼粥帚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起限次,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤芒涡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后卖漫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體费尽,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年懊亡,在試婚紗的時候發(fā)現(xiàn)自己被綠了依啰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡店枣,死狀恐怖速警,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鸯两,我是刑警寧澤闷旧,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站钧唐,受9級特大地震影響忙灼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一该园、第九天 我趴在偏房一處隱蔽的房頂上張望酸舍。 院中可真熱鬧,春花似錦里初、人聲如沸啃勉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽淮阐。三九已至,卻和暖如春刁品,著一層夾襖步出監(jiān)牢的瞬間泣特,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工挑随, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留状您,地道東北人。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓镀裤,卻偏偏與公主長得像竞阐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子暑劝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

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

  • RAC使用測試Demo下載:github.com/FuWees/WPRACTestDemo 1.ReactiveC...
    FuWees閱讀 6,355評論 3 10
  • 標(biāo)簽: iOS RAC 概述 ReactiveCocoa是一個函數(shù)響應(yīng)式編程框架骆莹,它能讓我們脫離Cocoa AP...
    GodyZ閱讀 7,510評論 16 97
  • 作為一個iOS開發(fā)者,你寫的每一行代碼幾乎都是在相應(yīng)某個事件担猛,例如按鈕的點擊幕垦,收到網(wǎng)絡(luò)消息,屬性的變化(通過KVO...
    jiajia1118閱讀 796評論 0 2
  • RAC支持的UI控件 RACCommand RACCommand類用于表示事件的執(zhí)行傅联,一般來說是在UI上的某些動作...
    花前月下閱讀 2,735評論 0 5
  • 最近有位編輯找我先改,問我認識不認識魔云獸,我說我倆是好朋友呀U糇摺(我真的沒吹牛仇奶,我倆真的是好朋友,不相信可以去問他比驻,不...
    鼴鼠的土豆閱讀 1,242評論 4 32