ReactiveCocoa學(xué)習(xí)筆記整理(三)

此文章是針對(duì)ReactiveCocoa的學(xué)習(xí)總結(jié)整理,該文是第三篇。我們這篇主要講解一下RACCommand以及RAC替換UIKit的典型例子柒室。未閱讀前兩篇的童鞋,吶喇完,給你傳送門伦泥。

五. RACCommand的基本簡(jiǎn)介跟使用

1. RACCommand簡(jiǎn)介以及使用

RACCommand是RAC中用于處理事件的類不脯,我們可以把事件如何處理,事件中的數(shù)據(jù)如何傳遞,包裝到這個(gè)類中刻诊。使用這個(gè)類可以很方便的監(jiān)控事件的執(zhí)行過程防楷。RACCommand的使用步驟可以總結(jié)為以下三點(diǎn):

  1. 創(chuàng)建命令 initWithSignalBlock:(RACSignal * (^)(id input))signalBlock
  2. 在signalBlock中,創(chuàng)建RACSignal则涯,并且作為signalBlock的返回值
  3. 執(zhí)行命令 -(RACSignal * )execute:(id)input
    在RAC的開發(fā)中复局,我們通常會(huì)把網(wǎng)絡(luò)請(qǐng)求封裝到RACCommand,直接執(zhí)行某個(gè)RACCommand就能發(fā)送請(qǐng)求粟判。然后當(dāng)RACCommand內(nèi)部請(qǐng)求到數(shù)據(jù)的時(shí)候亿昏,需要把請(qǐng)求的數(shù)據(jù)傳遞給外界,這時(shí)候就需要通過signalBlock返回的信號(hào)傳遞了档礁。
    那么我們?nèi)绾文玫絉ACCommand中返回信號(hào)發(fā)出的數(shù)據(jù)角钩?
  • RACCommand有個(gè)執(zhí)行信號(hào)源executionSignals,這個(gè)是signal of signals(信號(hào)的信號(hào)),意思是信號(hào)發(fā)出的數(shù)據(jù)是信號(hào),不是普通的類型递礼。
  • 訂閱executionSignals就能拿到RACCommand中返回的信號(hào)惨险,然后訂閱signalBlock返回的信號(hào),就能獲取發(fā)出的值脊髓。

在RACCommand的使用過程中辫愉,我們及其要注意以下的幾點(diǎn)事項(xiàng):

  • signalBlock必須要返回一個(gè)信號(hào),不能傳nil
  • 如果不想要傳遞信號(hào)将硝,直接創(chuàng)建空的信號(hào)[RACSignal empty]
  • RACCommand中信號(hào)如果數(shù)據(jù)傳遞完恭朗,必須調(diào)用[subscriber sendCompleted],這時(shí)命令才會(huì)執(zhí)行完畢袋哼,否則永遠(yuǎn)處于執(zhí)行中
  • RACCommand需要被強(qiáng)引用冀墨,否則接收不到RACCommand中的信號(hào),因此RACCommand中的信號(hào)是延遲發(fā)送的
    好了涛贯,大致了解了RACCommand的基本概念以及使用步驟之后诽嘉,我們通過簡(jiǎn)單的小實(shí)例來看一下RACCommand怎樣使用,接下來弟翘,我們模擬一下監(jiān)聽按鈕點(diǎn)擊虫腋,發(fā)送網(wǎng)絡(luò)請(qǐng)求的過程,請(qǐng)看代碼:
    // 1.創(chuàng)建命令
    RACCommand *command=[[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        NSLog(@"執(zhí)行命令");
        
        // 創(chuàng)建空信號(hào),必須返回信號(hào)
        //        return [RACSignal empty];
        
        // 2.創(chuàng)建信號(hào),用來傳遞數(shù)據(jù)
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
            [subscriber sendNext:@"請(qǐng)求數(shù)據(jù)"];
            
            // 注意:數(shù)據(jù)傳遞完稀余,最好調(diào)用sendCompleted悦冀,這時(shí)命令才執(zhí)行完畢。
            [subscriber sendCompleted];
            return nil;
        }];
    }];
    
    // 強(qiáng)引用命令睛琳,不要被銷毀盒蟆,否則接收不到數(shù)據(jù)
    _conmmand = command;
    
    // 3.訂閱RACCommand中的信號(hào)
    [command.executionSignals subscribeNext:^(id x) {
        
        [x subscribeNext:^(id x) {
            
            NSLog(@"executionSignals:%@",x);
        }];
    }];
    
    // RAC高級(jí)用法
    // switchToLatest:用于signal of signals,獲取signal of signals發(fā)出的最新信號(hào),也就是可以直接拿到RACCommand中的信號(hào)
    [command.executionSignals.switchToLatest subscribeNext:^(id x) {
        
        NSLog(@"executionSignals.switchToLatest:%@",x);
    }];
    
    // 4.監(jiān)聽命令是否執(zhí)行完畢,默認(rèn)會(huì)來一次师骗,可以直接跳過历等,skip表示跳過第一次信號(hào)。
    [[command.executing skip:1] subscribeNext:^(id x) {
        
        if ([x boolValue] == YES) {
            // 正在執(zhí)行
            NSLog(@"正在執(zhí)行");
            
        }else{
            // 執(zhí)行完成
            NSLog(@"執(zhí)行完成");
        }
        
    }];
    // 5.執(zhí)行命令
    [self.conmmand execute:@1];
    
    
//    輸出
//    執(zhí)行命令
//    正在執(zhí)行
//    executionSignals:請(qǐng)求數(shù)據(jù)
//    executionSignals.switchToLatest:請(qǐng)求數(shù)據(jù)
//    執(zhí)行完成

上述代碼就是使用RACCommand模擬的點(diǎn)擊按鈕進(jìn)行網(wǎng)絡(luò)請(qǐng)求的過程辟癌,可以看出寒屯,RACCommand可以很方便的處理事件以及事件中的數(shù)據(jù)傳遞。

2.RACMulticastConnection的使用

講到了RACCommand黍少,那么必不可少的有按鈕的多次點(diǎn)擊導(dǎo)致多次網(wǎng)絡(luò)請(qǐng)求的問題寡夹。RACMulticastConnection用于當(dāng)一個(gè)信號(hào),被多次訂閱時(shí)厂置,為了保證創(chuàng)建信號(hào)時(shí)菩掏,避免多次調(diào)用創(chuàng)建信號(hào)中的block,造成副作用昵济,可以使用這個(gè)類處理智绸。首先或颊,我們看一下RACMulticastConnection的使用步驟:

  1. 創(chuàng)建信號(hào) + (RACSignal *)createSignal:(RACDisposable * (^)(id<RACSubscriber> subscriber))didSubscribe
  2. 創(chuàng)建連接 RACMulticastConnection *connect = [signal publish];
  3. 訂閱信號(hào),注意:訂閱的不在是之前的信號(hào),而是連接的信號(hào)传于。 [connect.signal subscribeNext:nextBlock]
  4. 連接 [connect connect]

然后我們看一下RACMulticastConnection的底層實(shí)現(xiàn)原理:

  • 創(chuàng)建connect,connect.sourceSignal -> RACSignal(原始信號(hào)) connect.signal -> RACSubject
  • 訂閱connect.signal醉顽,會(huì)調(diào)用RACSubject的subscribeNext沼溜,創(chuàng)建訂閱者,而且把訂閱者保存起來游添,不會(huì)執(zhí)行block
  • [connect connect]內(nèi)部會(huì)訂閱RACSignal(原始信號(hào))系草,并且訂閱者是RACSubject
    訂閱原始信號(hào),就會(huì)調(diào)用原始信號(hào)中的didSubscribe
    didSubscribe唆涝,拿到訂閱者調(diào)用sendNext找都,其實(shí)是調(diào)用RACSubject的sendNext
  • RACSubject的sendNext,會(huì)遍歷RACSubject所有訂閱者發(fā)送信號(hào)
    因?yàn)閯倓偟诙剑际窃谟嗛哛ACSubject廊酣,因此會(huì)拿到第二步所有的訂閱者能耻,調(diào)用他們的nextBlock
    最后,我們通過簡(jiǎn)單的小需求來實(shí)際使用一下亡驰。假設(shè)在一個(gè)信號(hào)中發(fā)送請(qǐng)求晓猛,每次訂閱一次都會(huì)發(fā)送請(qǐng)求,這樣就會(huì)導(dǎo)致多次請(qǐng)求凡辱。我們需要使用RACMulticastConnection解決這個(gè)問題戒职。
  // 1.創(chuàng)建請(qǐng)求信號(hào)
    RACSignal *aSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        
        NSLog(@"aSignal發(fā)送請(qǐng)求");
        
        return nil;
    }];
    // 2.訂閱信號(hào)
    [aSignal subscribeNext:^(id x) {
        
        NSLog(@"接收數(shù)據(jù)");
        
    }];
    // 2.訂閱信號(hào)
    [aSignal subscribeNext:^(id x) {
        
        NSLog(@"接收數(shù)據(jù)");
        
    }];
    
    // 3.運(yùn)行結(jié)果,會(huì)執(zhí)行兩遍發(fā)送請(qǐng)求透乾,也就是每次訂閱都會(huì)發(fā)送一次請(qǐng)求
 
    // RACMulticastConnection:解決重復(fù)請(qǐng)求問題
    // 1.創(chuàng)建信號(hào)
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        
        NSLog(@"signal發(fā)送請(qǐng)求");
        [subscriber sendNext:@1];
        
        return nil;
    }];
    
    // 2.創(chuàng)建連接
    RACMulticastConnection *connect = [signal publish];
    
    // 3.訂閱信號(hào)洪燥,
    // 注意:訂閱信號(hào),也不能激活信號(hào)乳乌,只是保存訂閱者到數(shù)組捧韵,必須通過連接,當(dāng)調(diào)用連接,就會(huì)一次性調(diào)用所有訂閱者的sendNext:
    [connect.signal subscribeNext:^(id x) {
        
        NSLog(@"訂閱者一信號(hào)");
        
    }];
    
    [connect.signal subscribeNext:^(id x) {
        
        NSLog(@"訂閱者二信號(hào)");
        
    }];
    
    // 4.連接,激活信號(hào)
    [connect connect];
    
    
    
    //輸出
    //aSignal發(fā)送請(qǐng)求
    //aSignal發(fā)送請(qǐng)求
    
    
    //signal發(fā)送請(qǐng)求
    //訂閱者一信號(hào)
    //訂閱者二信號(hào)

通過以上的代碼钦扭,可以明確的看出纫版, aSignal被執(zhí)行的兩次,雖然有兩個(gè)訂閱者 客情,但其實(shí)只要執(zhí)行一次就可以其弊。使用RACMulticastConnection我們解決了這個(gè)問題。
截止此文膀斋,RAC的筆記就先到這吧梭伐,其實(shí)RAC還有很多高階用法以及更大的發(fā)揮空間,剩下的就由你們自己去慢慢發(fā)掘吧仰担。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末糊识,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赂苗,老刑警劉巖愉耙,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異拌滋,居然都是意外死亡朴沿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門败砂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赌渣,“玉大人,你說我怎么就攤上這事昌犹〖嵛撸” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵斜姥,是天一觀的道長(zhǎng)鸿竖。 經(jīng)常有香客問我,道長(zhǎng)铸敏,這世上最難降的妖魔是什么千贯? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮搞坝,結(jié)果婚禮上搔谴,老公的妹妹穿的比我還像新娘。我一直安慰自己桩撮,他們只是感情好敦第,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著店量,像睡著了一般芜果。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上融师,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天右钾,我揣著相機(jī)與錄音,去河邊找鬼旱爆。 笑死舀射,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的怀伦。 我是一名探鬼主播脆烟,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼房待!你這毒婦竟也來了邢羔?” 一聲冷哼從身側(cè)響起驼抹,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拜鹤,沒想到半個(gè)月后框冀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡敏簿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年左驾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片极谊。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖安岂,靈堂內(nèi)的尸體忽然破棺而出轻猖,到底是詐尸還是另有隱情,我是刑警寧澤域那,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布咙边,位于F島的核電站,受9級(jí)特大地震影響次员,放射性物質(zhì)發(fā)生泄漏败许。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一淑蔚、第九天 我趴在偏房一處隱蔽的房頂上張望市殷。 院中可真熱鬧,春花似錦刹衫、人聲如沸醋寝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽音羞。三九已至,卻和暖如春仓犬,著一層夾襖步出監(jiān)牢的瞬間嗅绰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工搀继, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窘面,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓叽躯,卻偏偏與公主長(zhǎng)得像民镜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子险毁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

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